From 4f6381ed28d84bb9664267674c2cab256368a295 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Wed, 18 Jan 2023 08:03:42 +0000 Subject: [PATCH 001/109] doc: use latest version for master branch --- charts/index.yaml | 74 +++++++++--------- charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 0 -> 11435 bytes .../latest/azurefile-csi-driver-v1.25.1.tgz | Bin 11419 -> 0 bytes charts/latest/azurefile-csi-driver/Chart.yaml | 4 +- .../latest/azurefile-csi-driver/values.yaml | 4 +- deploy/csi-azurefile-controller.yaml | 2 +- deploy/csi-azurefile-node-windows.yaml | 2 +- deploy/csi-azurefile-node.yaml | 2 +- 8 files changed, 44 insertions(+), 44 deletions(-) create mode 100644 charts/latest/azurefile-csi-driver-v0.0.0.tgz delete mode 100644 charts/latest/azurefile-csi-driver-v1.25.1.tgz diff --git a/charts/index.yaml b/charts/index.yaml index 9447486176..e1b74c5e16 100644 --- a/charts/index.yaml +++ b/charts/index.yaml @@ -3,16 +3,7 @@ entries: azurefile-csi-driver: - apiVersion: v1 appVersion: v1.25.1 - created: "2023-01-18T08:02:39.127092944Z" - description: Azure File Container Storage Interface (CSI) Storage Plugin - digest: 7a370213ae427f16b85502c2cc3e34c8a88bd01fa75a049cb29f97e7a2b4e9bb - name: azurefile-csi-driver - urls: - - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/latest/azurefile-csi-driver-v1.25.1.tgz - version: v1.25.1 - - apiVersion: v1 - appVersion: v1.25.1 - created: "2023-01-18T08:02:39.223617512Z" + created: "2023-01-18T08:03:41.908826298Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 2bf374cc321c5bc8e76e06cd5df85ce7d7d14574397e7e7f7173077393f554c4 name: azurefile-csi-driver @@ -21,7 +12,7 @@ entries: version: v1.25.1 - apiVersion: v1 appVersion: v1.25.0 - created: "2023-01-18T08:02:39.221994896Z" + created: "2023-01-18T08:03:41.906575576Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: ba80dcd23dade4e62b39d3dc638c599e9d5e100009fa14d4164bfc8966fea3dd name: azurefile-csi-driver @@ -30,7 +21,7 @@ entries: version: v1.25.0 - apiVersion: v1 appVersion: v1.24.0 - created: "2023-01-18T08:02:39.219469571Z" + created: "2023-01-18T08:03:41.905098661Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 1905eb862745d4a7f57c5de96848cee194adf827086984b75bcaefce5c90142b name: azurefile-csi-driver @@ -39,7 +30,7 @@ entries: version: v1.24.0 - apiVersion: v1 appVersion: v1.23.0 - created: "2023-01-18T08:02:39.216986446Z" + created: "2023-01-18T08:03:41.903343544Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 5fcb33617d16e90df1e7041b0df02e5bd92595e86381db30d356b0b2e3500bc4 name: azurefile-csi-driver @@ -48,7 +39,7 @@ entries: version: v1.23.0 - apiVersion: v1 appVersion: v1.22.0 - created: "2023-01-18T08:02:39.212359299Z" + created: "2023-01-18T08:03:41.901897329Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 253d87a8b876dbdd55870a7fee88547393179d03f193661125f5a0b63411f922 name: azurefile-csi-driver @@ -57,7 +48,7 @@ entries: version: v1.22.0 - apiVersion: v1 appVersion: v1.21.0 - created: "2023-01-18T08:02:39.207913455Z" + created: "2023-01-18T08:03:41.900301813Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: d45bf3455ebadc9cc5afaf9da66aa1ea1d4b719cfdff5af661f93bb26c01a504 name: azurefile-csi-driver @@ -66,7 +57,7 @@ entries: version: v1.21.0 - apiVersion: v1 appVersion: v1.20.0 - created: "2023-01-18T08:02:39.200109377Z" + created: "2023-01-18T08:03:41.89805449Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 7cc43d57a79137aea5414fb51a9bbd77bb679b29ee49c06865c1a5b9ba60be99 name: azurefile-csi-driver @@ -75,7 +66,7 @@ entries: version: v1.20.0 - apiVersion: v1 appVersion: v1.19.0 - created: "2023-01-18T08:02:39.192792403Z" + created: "2023-01-18T08:03:41.896063471Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 18f6efbed424efd661fde43be2e5a48a5012a46a7938c33b36963cbd9875a5af name: azurefile-csi-driver @@ -84,7 +75,7 @@ entries: version: v1.19.0 - apiVersion: v1 appVersion: v1.18.0 - created: "2023-01-18T08:02:39.18745915Z" + created: "2023-01-18T08:03:41.894651456Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 696ca23d9ee517f71ef5e852955c8d0f1017c331c025426c6fcbe7a06d006c66 name: azurefile-csi-driver @@ -93,7 +84,7 @@ entries: version: v1.18.0 - apiVersion: v1 appVersion: v1.17.0 - created: "2023-01-18T08:02:39.183002705Z" + created: "2023-01-18T08:03:41.893267042Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 5632f61265a3b78dce3e2b15e07cc9b14a7f54a778878c02ca2d9fe69ca0344e name: azurefile-csi-driver @@ -102,7 +93,7 @@ entries: version: v1.17.0 - apiVersion: v1 appVersion: v1.16.0 - created: "2023-01-18T08:02:39.178305858Z" + created: "2023-01-18T08:03:41.89199333Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: a7a2d57e8eca7dc06c8b2cffb9bccb857753eb110b8e70760b3e04f4e6a87552 name: azurefile-csi-driver @@ -111,7 +102,7 @@ entries: version: v1.16.0 - apiVersion: v1 appVersion: v1.15.0 - created: "2023-01-18T08:02:39.173366208Z" + created: "2023-01-18T08:03:41.889838908Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: c1a31dadce233a90c19dce70f6cc92ba2e20bbaa1b1883baea72381d09303118 name: azurefile-csi-driver @@ -120,7 +111,7 @@ entries: version: v1.15.0 - apiVersion: v1 appVersion: v1.14.0 - created: "2023-01-18T08:02:39.167031745Z" + created: "2023-01-18T08:03:41.888541195Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 0c9ad4afa5ebfdb2851ad93eb16a0382d61448714b7556899360730a2fdf463a name: azurefile-csi-driver @@ -129,7 +120,7 @@ entries: version: v1.14.0 - apiVersion: v1 appVersion: v1.13.0 - created: "2023-01-18T08:02:39.162296497Z" + created: "2023-01-18T08:03:41.887146481Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 214042b029d858b50a0f8bba33a7aa2b41d1b67bce16f957ca183ae7438dac3f name: azurefile-csi-driver @@ -138,7 +129,7 @@ entries: version: v1.13.0 - apiVersion: v1 appVersion: v1.12.0 - created: "2023-01-18T08:02:39.15761205Z" + created: "2023-01-18T08:03:41.885874068Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: fbd63929671066a26df898d32282a6e79c39499a39c71761c546d069459d847d name: azurefile-csi-driver @@ -147,7 +138,7 @@ entries: version: v1.12.0 - apiVersion: v1 appVersion: v1.11.0 - created: "2023-01-18T08:02:39.155457529Z" + created: "2023-01-18T08:03:41.884300753Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 76bd438f8391d08235b09fbca859f25a9fcf8e018fd1e7e33444ca9ea946ce4b name: azurefile-csi-driver @@ -156,7 +147,7 @@ entries: version: v1.11.0 - apiVersion: v1 appVersion: v1.10.0 - created: "2023-01-18T08:02:39.150953884Z" + created: "2023-01-18T08:03:41.881607826Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 845a9de8b571b255d05ae9c643d9b90a57fe6507ff3fb735c88b41f99f6f28dc name: azurefile-csi-driver @@ -165,7 +156,7 @@ entries: version: v1.10.0 - apiVersion: v1 appVersion: v1.9.0 - created: "2023-01-18T08:02:39.248963266Z" + created: "2023-01-18T08:03:41.917453285Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 59a8057fbbd6d59919b84ef0c3396d5a0a46d1f29df604457db676f4af63c714 name: azurefile-csi-driver @@ -174,7 +165,7 @@ entries: version: v1.9.0 - apiVersion: v1 appVersion: v1.8.0 - created: "2023-01-18T08:02:39.244444121Z" + created: "2023-01-18T08:03:41.91598967Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 455b7c342194311046df526d10926d94f3bef24f753a07003fb1cad211c4cb52 name: azurefile-csi-driver @@ -183,7 +174,7 @@ entries: version: v1.8.0 - apiVersion: v1 appVersion: v1.7.0 - created: "2023-01-18T08:02:39.239999777Z" + created: "2023-01-18T08:03:41.913636147Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 057b3f6ef6001d3457fbffc27f90316c981a089696abd3d38bcc8de5537dfa6f name: azurefile-csi-driver @@ -192,7 +183,7 @@ entries: version: v1.7.0 - apiVersion: v1 appVersion: v1.6.0 - created: "2023-01-18T08:02:39.234994826Z" + created: "2023-01-18T08:03:41.912616936Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: cc2a0dda824cdda4e8141e26878bbb481c5a52e45785a5dbf72e54f2a376e522 name: azurefile-csi-driver @@ -201,7 +192,7 @@ entries: version: v1.6.0 - apiVersion: v1 appVersion: v1.5.0 - created: "2023-01-18T08:02:39.230759984Z" + created: "2023-01-18T08:03:41.911505825Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 2258177477415ddecd83dc46dfd88833223623224c7fe396590b617082bcd845 name: azurefile-csi-driver @@ -210,7 +201,7 @@ entries: version: v1.5.0 - apiVersion: v1 appVersion: v1.4.0 - created: "2023-01-18T08:02:39.226727343Z" + created: "2023-01-18T08:03:41.910547616Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 40e9bc4ee187789166fcb7c3c82b85b33ecd3a6096266fe74e411d6b48961ece name: azurefile-csi-driver @@ -219,7 +210,7 @@ entries: version: v1.4.0 - apiVersion: v1 appVersion: v1.3.0 - created: "2023-01-18T08:02:39.225126927Z" + created: "2023-01-18T08:03:41.909586706Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 12942f422b7cccbfe950bbdbd5c844f5ae4b7c292f32389cba312730a6fe9a62 name: azurefile-csi-driver @@ -228,7 +219,7 @@ entries: version: v1.3.0 - apiVersion: v1 appVersion: v1.2.0 - created: "2023-01-18T08:02:39.194265618Z" + created: "2023-01-18T08:03:41.896767678Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: b62f44b757416a9e1f5a91e19285f5f5056ec6068802dd9cd82373bef40c9ee9 name: azurefile-csi-driver @@ -237,7 +228,7 @@ entries: version: v1.2.0 - apiVersion: v1 appVersion: v1.1.0 - created: "2023-01-18T08:02:39.135475928Z" + created: "2023-01-18T08:03:41.880325313Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 675d96b309a1c5c491053ebbb854c046737420929c4f0692839afdaaf0db3933 name: azurefile-csi-driver @@ -246,11 +237,20 @@ entries: version: v1.1.0 - apiVersion: v1 appVersion: v1.0.0 - created: "2023-01-18T08:02:39.131407088Z" + created: "2023-01-18T08:03:41.879587105Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 6fd5e54e949ef1061a08d5477bc580204c91dde8f01da195e95dd60ade209492 name: azurefile-csi-driver urls: - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/v1.0.0/azurefile-csi-driver-v1.0.0.tgz version: v1.0.0 -generated: "2023-01-18T08:02:39.125208125Z" + - apiVersion: v1 + appVersion: latest + created: "2023-01-18T08:03:41.878783397Z" + description: Azure File Container Storage Interface (CSI) Storage Plugin + digest: 374f40b7c22c45f91b9557ffebede2be3d9dfc217e44a78d11e9fc76478ee28f + name: azurefile-csi-driver + urls: + - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/latest/azurefile-csi-driver-v0.0.0.tgz + version: v0.0.0 +generated: "2023-01-18T08:03:41.877114781Z" diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..965bb9451777081fcfee43c9d0dcf9794d6a795c GIT binary patch literal 11435 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 E2ioDLr~m)} diff --git a/charts/latest/azurefile-csi-driver/Chart.yaml b/charts/latest/azurefile-csi-driver/Chart.yaml index cee609a62c..27ff7d757c 100644 --- a/charts/latest/azurefile-csi-driver/Chart.yaml +++ b/charts/latest/azurefile-csi-driver/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: v1.25.1 +appVersion: latest description: Azure File Container Storage Interface (CSI) Storage Plugin name: azurefile-csi-driver -version: v1.25.1 +version: v0.0.0 diff --git a/charts/latest/azurefile-csi-driver/values.yaml b/charts/latest/azurefile-csi-driver/values.yaml index 866ba0c83c..50f8a7c731 100644 --- a/charts/latest/azurefile-csi-driver/values.yaml +++ b/charts/latest/azurefile-csi-driver/values.yaml @@ -1,8 +1,8 @@ image: baseRepo: mcr.microsoft.com azurefile: - repository: /oss/kubernetes-csi/azurefile-csi - tag: v1.25.1 + repository: /k8s/csi/azurefile-csi + tag: latest pullPolicy: IfNotPresent csiProvisioner: repository: /oss/kubernetes-csi/csi-provisioner diff --git a/deploy/csi-azurefile-controller.yaml b/deploy/csi-azurefile-controller.yaml index 9feb0caee7..623890f3ee 100644 --- a/deploy/csi-azurefile-controller.yaml +++ b/deploy/csi-azurefile-controller.yaml @@ -133,7 +133,7 @@ spec: cpu: 10m memory: 20Mi - name: azurefile - image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.25.1 + image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest imagePullPolicy: IfNotPresent args: - "--v=5" diff --git a/deploy/csi-azurefile-node-windows.yaml b/deploy/csi-azurefile-node-windows.yaml index 032b2015c0..9340864653 100644 --- a/deploy/csi-azurefile-node-windows.yaml +++ b/deploy/csi-azurefile-node-windows.yaml @@ -91,7 +91,7 @@ spec: cpu: 30m memory: 40Mi - name: azurefile - image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.25.1 + image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest imagePullPolicy: IfNotPresent args: - --v=5 diff --git a/deploy/csi-azurefile-node.yaml b/deploy/csi-azurefile-node.yaml index 4110634636..f36a6a9545 100644 --- a/deploy/csi-azurefile-node.yaml +++ b/deploy/csi-azurefile-node.yaml @@ -82,7 +82,7 @@ spec: cpu: 10m memory: 20Mi - name: azurefile - image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.25.1 + image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest imagePullPolicy: IfNotPresent args: - "--v=5" From b57c5ca2e793fc618dbcb57e09edbaeebadf7615 Mon Sep 17 00:00:00 2001 From: Paul Yu Date: Thu, 26 Jan 2023 13:29:53 -0800 Subject: [PATCH 002/109] doc: Fix URL to azure-files-csi driver doc in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cc13c28ae1..6c8c354d17 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ### About This driver allows Kubernetes to access [Azure File](https://docs.microsoft.com/en-us/azure/storage/files/storage-files-introduction) volume using smb and nfs protocols, csi plugin name: `file.csi.azure.com` -Disclaimer: Deploying this driver manually is not an officially supported Microsoft product. For a fully managed and supported experience on Kubernetes, use [AKS with the managed Azure file csi driver](https://learn.microsoft.com/en-us/azure/aks/azure-file-csi). +Disclaimer: Deploying this driver manually is not an officially supported Microsoft product. For a fully managed and supported experience on Kubernetes, use [AKS with the managed Azure file csi driver](https://learn.microsoft.com/azure/aks/azure-files-csi). ### Project status: GA From 38e7f23c91488819c3ba76b2df5a19d34fb4b380 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Mon, 30 Jan 2023 07:47:57 +0000 Subject: [PATCH 003/109] fix: incorrect driver version in CSIDriver --- deploy/csi-azurefile-driver.yaml | 2 +- deploy/v1.21.0/csi-azurefile-driver.yaml | 2 +- deploy/v1.22.0/csi-azurefile-driver.yaml | 2 +- deploy/v1.23.0/csi-azurefile-driver.yaml | 2 +- deploy/v1.24.0/csi-azurefile-driver.yaml | 2 +- deploy/v1.25.0/csi-azurefile-driver.yaml | 2 +- deploy/v1.25.1/csi-azurefile-driver.yaml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/deploy/csi-azurefile-driver.yaml b/deploy/csi-azurefile-driver.yaml index 3190ff2423..55d31ed2d1 100644 --- a/deploy/csi-azurefile-driver.yaml +++ b/deploy/csi-azurefile-driver.yaml @@ -4,7 +4,7 @@ kind: CSIDriver metadata: name: file.csi.azure.com annotations: - csiDriver: v1.20.0 + csiDriver: latest snapshot: v5.0.1 spec: attachRequired: false diff --git a/deploy/v1.21.0/csi-azurefile-driver.yaml b/deploy/v1.21.0/csi-azurefile-driver.yaml index 3190ff2423..e53f4f1f1f 100644 --- a/deploy/v1.21.0/csi-azurefile-driver.yaml +++ b/deploy/v1.21.0/csi-azurefile-driver.yaml @@ -4,7 +4,7 @@ kind: CSIDriver metadata: name: file.csi.azure.com annotations: - csiDriver: v1.20.0 + csiDriver: v1.21.0 snapshot: v5.0.1 spec: attachRequired: false diff --git a/deploy/v1.22.0/csi-azurefile-driver.yaml b/deploy/v1.22.0/csi-azurefile-driver.yaml index 3190ff2423..4723ee72c0 100644 --- a/deploy/v1.22.0/csi-azurefile-driver.yaml +++ b/deploy/v1.22.0/csi-azurefile-driver.yaml @@ -4,7 +4,7 @@ kind: CSIDriver metadata: name: file.csi.azure.com annotations: - csiDriver: v1.20.0 + csiDriver: v1.22.0 snapshot: v5.0.1 spec: attachRequired: false diff --git a/deploy/v1.23.0/csi-azurefile-driver.yaml b/deploy/v1.23.0/csi-azurefile-driver.yaml index 3190ff2423..93226017b4 100644 --- a/deploy/v1.23.0/csi-azurefile-driver.yaml +++ b/deploy/v1.23.0/csi-azurefile-driver.yaml @@ -4,7 +4,7 @@ kind: CSIDriver metadata: name: file.csi.azure.com annotations: - csiDriver: v1.20.0 + csiDriver: v1.23.0 snapshot: v5.0.1 spec: attachRequired: false diff --git a/deploy/v1.24.0/csi-azurefile-driver.yaml b/deploy/v1.24.0/csi-azurefile-driver.yaml index 3190ff2423..d7e4e4dd45 100644 --- a/deploy/v1.24.0/csi-azurefile-driver.yaml +++ b/deploy/v1.24.0/csi-azurefile-driver.yaml @@ -4,7 +4,7 @@ kind: CSIDriver metadata: name: file.csi.azure.com annotations: - csiDriver: v1.20.0 + csiDriver: v1.24.0 snapshot: v5.0.1 spec: attachRequired: false diff --git a/deploy/v1.25.0/csi-azurefile-driver.yaml b/deploy/v1.25.0/csi-azurefile-driver.yaml index 3190ff2423..d851767af7 100644 --- a/deploy/v1.25.0/csi-azurefile-driver.yaml +++ b/deploy/v1.25.0/csi-azurefile-driver.yaml @@ -4,7 +4,7 @@ kind: CSIDriver metadata: name: file.csi.azure.com annotations: - csiDriver: v1.20.0 + csiDriver: v1.25.0 snapshot: v5.0.1 spec: attachRequired: false diff --git a/deploy/v1.25.1/csi-azurefile-driver.yaml b/deploy/v1.25.1/csi-azurefile-driver.yaml index 3190ff2423..7d380f6d79 100644 --- a/deploy/v1.25.1/csi-azurefile-driver.yaml +++ b/deploy/v1.25.1/csi-azurefile-driver.yaml @@ -4,7 +4,7 @@ kind: CSIDriver metadata: name: file.csi.azure.com annotations: - csiDriver: v1.20.0 + csiDriver: v1.25.1 snapshot: v5.0.1 spec: attachRequired: false From 11f8d03fb4a68a3315eb4e11b5bbca961b01a2db Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Sun, 5 Feb 2023 08:07:09 +0000 Subject: [PATCH 004/109] feat: add support for SMB Multi-channels in premium account creation fix typo --- docs/driver-parameters.md | 1 + pkg/azurefile/azurefile.go | 1 + pkg/azurefile/controllerserver.go | 24 +++++++++++++++++++----- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/docs/driver-parameters.md b/docs/driver-parameters.md index d35e8badb2..af1259b1e4 100644 --- a/docs/driver-parameters.md +++ b/docs/driver-parameters.md @@ -31,6 +31,7 @@ storeAccountKey | whether store account key to k8s secret

Note:
` secretName | specify secret name to store account key | | No | secretNamespace | specify the namespace of secret to store account key | `default`,`kube-system`, etc | No | pvc namespace (`csi.storage.k8s.io/pvc/namespace`) useDataPlaneAPI | specify whether use [data plane API](https://github.com/Azure/azure-sdk-for-go/blob/master/storage/share.go) for file share create/delete/resize, this could solve the SRP API throltting issue since data plane API has almost no limit, while it would fail when there is firewall or vnet setting on storage account | `true`,`false` | No | `false` +enableMultichannel | specify whether enable [SMB multi-channel](https://learn.microsoft.com/en-us/azure/storage/files/files-smb-protocol?tabs=azure-portal#smb-multichannel) for **Premium** storage account
Note: this feature is used with `max_channels=2` (or 3,4) mount option, only available on AKS 1.25+ or Mariner 2.0 node | `true`,`false` | No | `false` --- | **Following parameters are only for NFS protocol** | --- | --- | rootSquashType | specify root squashing behavior on the share. The default is `NoRootSquash` | `AllSquash`, `NoRootSquash`, `RootSquash` | No | mountPermissions | mounted folder permissions. The default is `0777`, if set as `0`, driver will not perform `chmod` after mount | `0777` | No | diff --git a/pkg/azurefile/azurefile.go b/pkg/azurefile/azurefile.go index 9fc668c0b4..eee1a79dcd 100644 --- a/pkg/azurefile/azurefile.go +++ b/pkg/azurefile/azurefile.go @@ -130,6 +130,7 @@ const ( subnetNameField = "subnetname" shareNamePrefixField = "sharenameprefix" requireInfraEncryptionField = "requireinfraencryption" + enableMultichannelField = "enablemultichannel" premium = "premium" accountNotProvisioned = "StorageAccountIsNotProvisioned" diff --git a/pkg/azurefile/controllerserver.go b/pkg/azurefile/controllerserver.go index c7a503ce0c..fb294eb5f4 100644 --- a/pkg/azurefile/controllerserver.go +++ b/pkg/azurefile/controllerserver.go @@ -115,7 +115,7 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) var secretNamespace, pvcNamespace, protocol, customTags, storageEndpointSuffix, networkEndpointType, shareAccessTier, accountAccessTier, rootSquashType string var createAccount, useDataPlaneAPI, useSeretCache, matchTags bool var vnetResourceGroup, vnetName, subnetName, shareNamePrefix, fsGroupChangePolicy string - var requireInfraEncryption, disableDeleteRetentionPolicy, enableLFS *bool + var requireInfraEncryption, disableDeleteRetentionPolicy, enableLFS, isMultichannelEnabled *bool // set allowBlobPublicAccess as false by default allowBlobPublicAccess := pointer.Bool(false) @@ -210,10 +210,8 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) fsGroupChangePolicy = v case mountPermissionsField: // only do validations here, used in NodeStageVolume, NodePublishVolume - if v != "" { - if _, err := strconv.ParseUint(v, 8, 32); err != nil { - return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("invalid mountPermissions %s in storage class", v)) - } + if _, err := strconv.ParseUint(v, 8, 32); err != nil { + return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("invalid mountPermissions %s in storage class", v)) } case vnetResourceGroupField: vnetResourceGroup = v @@ -229,6 +227,12 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("invalid %s: %s in storage class", requireInfraEncryptionField, v)) } requireInfraEncryption = &value + case enableMultichannelField: + value, err := strconv.ParseBool(v) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("invalid %s: %s in storage class", enableMultichannelField, v)) + } + isMultichannelEnabled = &value default: return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("invalid parameter %q in storage class", k)) } @@ -319,6 +323,15 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) } } + if pointer.BoolDeref(isMultichannelEnabled, false) { + if sku != "" && !strings.HasPrefix(strings.ToLower(sku), premium) { + return nil, status.Errorf(codes.InvalidArgument, "smb multichannel is only supported with premium account, current account type: %s", sku) + } + if fsType == nfs || protocol == nfs { + return nil, status.Errorf(codes.InvalidArgument, "smb multichannel is only supported with smb protocol, current protocol: %s", protocol) + } + } + fileShareSize := int(requestGiB) // account kind should be FileStorage for Premium File accountKind := string(storage.KindStorageV2) @@ -390,6 +403,7 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) AccessTier: accountAccessTier, StorageType: provider.StorageTypeFile, StorageEndpointSuffix: storageEndpointSuffix, + IsMultichannelEnabled: isMultichannelEnabled, } var accountKey, lockKey string From 7f4cacaf3dc7c492a7e60cbb58bfdd8801ee711d Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Sun, 5 Feb 2023 08:07:51 +0000 Subject: [PATCH 005/109] test: add smb multi-channel account creation e2e test --- test/e2e/dynamic_provisioning_test.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/e2e/dynamic_provisioning_test.go b/test/e2e/dynamic_provisioning_test.go index 3627b8eb0f..28ce223982 100644 --- a/test/e2e/dynamic_provisioning_test.go +++ b/test/e2e/dynamic_provisioning_test.go @@ -341,8 +341,11 @@ var _ = ginkgo.Describe("Dynamic Provisioning", func() { reclaimPolicy := v1.PersistentVolumeReclaimRetain volumes := []testsuites.VolumeDetails{ { - FSType: "ext4", - ClaimSize: "10Gi", + FSType: "ext4", + ClaimSize: "10Gi", + MountOptions: []string{ + "max_channels=2", + }, ReclaimPolicy: &reclaimPolicy, }, } From 43813c4c16e16fc9d4f6d503eef64891e26d916b Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Sun, 5 Feb 2023 11:12:14 +0000 Subject: [PATCH 006/109] test: refine multi-channel e2e test --- test/e2e/dynamic_provisioning_test.go | 41 +++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/test/e2e/dynamic_provisioning_test.go b/test/e2e/dynamic_provisioning_test.go index 28ce223982..d7e771458c 100644 --- a/test/e2e/dynamic_provisioning_test.go +++ b/test/e2e/dynamic_provisioning_test.go @@ -149,6 +149,40 @@ var _ = ginkgo.Describe("Dynamic Provisioning", func() { test.Run(cs, ns) }) + ginkgo.It("should create a smb multi-channel volume with max_channels options [file.csi.azure.com] [Windows]", func() { + skipIfUsingInTreeVolumePlugin() + pods := []testsuites.PodDetails{ + { + Cmd: convertToPowershellCommandIfNecessary("echo 'hello world' > /mnt/test-1/data && grep 'hello world' /mnt/test-1/data"), + Volumes: []testsuites.VolumeDetails{ + { + ClaimSize: "100Gi", + MountOptions: []string{ + "max_channels=2", + }, + VolumeMount: testsuites.VolumeMountDetails{ + NameGenerate: "test-volume-", + MountPathGenerate: "/mnt/test-", + }, + }, + }, + IsWindows: isWindowsCluster, + WinServerVer: winServerVer, + }, + } + + scParameters := map[string]string{ + "skuName": "Premium_LRS", + "enableMultichannel": "true", + } + test := testsuites.DynamicallyProvisionedCmdVolumeTest{ + CSIDriver: testDriver, + Pods: pods, + StorageClassParameters: scParameters, + } + test.Run(cs, ns) + }) + ginkgo.It("should create a pod with volume mount subpath [file.csi.azure.com] [Windows]", func() { skipIfUsingInTreeVolumePlugin() @@ -341,11 +375,8 @@ var _ = ginkgo.Describe("Dynamic Provisioning", func() { reclaimPolicy := v1.PersistentVolumeReclaimRetain volumes := []testsuites.VolumeDetails{ { - FSType: "ext4", - ClaimSize: "10Gi", - MountOptions: []string{ - "max_channels=2", - }, + FSType: "ext4", + ClaimSize: "10Gi", ReclaimPolicy: &reclaimPolicy, }, } From 851113ba128e91846b71e70ffdc1243dbc5eeb29 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Mon, 6 Feb 2023 02:01:26 +0000 Subject: [PATCH 007/109] test: skip aks-engine test for multi-channel test fxi test --- test/e2e/dynamic_provisioning_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/e2e/dynamic_provisioning_test.go b/test/e2e/dynamic_provisioning_test.go index d7e771458c..87ddad8bce 100644 --- a/test/e2e/dynamic_provisioning_test.go +++ b/test/e2e/dynamic_provisioning_test.go @@ -151,6 +151,9 @@ var _ = ginkgo.Describe("Dynamic Provisioning", func() { ginkgo.It("should create a smb multi-channel volume with max_channels options [file.csi.azure.com] [Windows]", func() { skipIfUsingInTreeVolumePlugin() + if !isCapzTest { + ginkgo.Skip("test case is only available for capz test") + } pods := []testsuites.PodDetails{ { Cmd: convertToPowershellCommandIfNecessary("echo 'hello world' > /mnt/test-1/data && grep 'hello world' /mnt/test-1/data"), @@ -1124,7 +1127,6 @@ var _ = ginkgo.Describe("Dynamic Provisioning", func() { ginkgo.It("should mount on-prem smb server [file.csi.azure.com]", func() { skipIfUsingInTreeVolumePlugin() if isWindowsCluster && isCapzTest { - log.Println("test case is not available for capz Windows test") ginkgo.Skip("test case is not available for capz Windows test") } From ba7e57823d18ca40070f7af9ea2e2548c2343b51 Mon Sep 17 00:00:00 2001 From: Andy Zhang Date: Tue, 7 Feb 2023 19:39:44 +0800 Subject: [PATCH 008/109] Update driver-parameters.md --- docs/driver-parameters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/driver-parameters.md b/docs/driver-parameters.md index af1259b1e4..b4912cd719 100644 --- a/docs/driver-parameters.md +++ b/docs/driver-parameters.md @@ -31,7 +31,7 @@ storeAccountKey | whether store account key to k8s secret

Note:
` secretName | specify secret name to store account key | | No | secretNamespace | specify the namespace of secret to store account key | `default`,`kube-system`, etc | No | pvc namespace (`csi.storage.k8s.io/pvc/namespace`) useDataPlaneAPI | specify whether use [data plane API](https://github.com/Azure/azure-sdk-for-go/blob/master/storage/share.go) for file share create/delete/resize, this could solve the SRP API throltting issue since data plane API has almost no limit, while it would fail when there is firewall or vnet setting on storage account | `true`,`false` | No | `false` -enableMultichannel | specify whether enable [SMB multi-channel](https://learn.microsoft.com/en-us/azure/storage/files/files-smb-protocol?tabs=azure-portal#smb-multichannel) for **Premium** storage account
Note: this feature is used with `max_channels=2` (or 3,4) mount option, only available on AKS 1.25+ or Mariner 2.0 node | `true`,`false` | No | `false` +enableMultichannel | specify whether enable [SMB multi-channel](https://learn.microsoft.com/en-us/azure/storage/files/files-smb-protocol?tabs=azure-portal#smb-multichannel) for **Premium** storage account
Note: this feature is used with `max_channels=4` (or 2,3) mount option, only available on AKS 1.25+ or Mariner 2.0 node | `true`,`false` | No | `false` --- | **Following parameters are only for NFS protocol** | --- | --- | rootSquashType | specify root squashing behavior on the share. The default is `NoRootSquash` | `AllSquash`, `NoRootSquash`, `RootSquash` | No | mountPermissions | mounted folder permissions. The default is `0777`, if set as `0`, driver will not perform `chmod` after mount | `0777` | No | From 0b303fdad4841a022ad275371154f09b6fb6eaf2 Mon Sep 17 00:00:00 2001 From: Andy Zhang Date: Wed, 8 Feb 2023 21:06:30 +0800 Subject: [PATCH 009/109] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6c8c354d17..02ed733d27 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,10 @@ This option does not depend on cloud provider config file, supports cross subscr ### Install driver on a Kubernetes cluster - install by [helm charts](./charts) - install by [kubectl](./docs/install-azurefile-csi-driver.md) - - install open source csi driver on AKS, follow guide [here](./docs/install-driver-on-aks.md) - - install managed csi driver on following platforms: + - install open source CSI driver on following platforms: + - [AKS](./docs/install-driver-on-aks.md) + - [Azure RedHat OpenShift](https://github.com/ezYakaEagle442/aro-pub-storage/blob/master/setup-store-CSI-driver-azure-file.md) + - install managed CSI driver on following platforms: - [AKS](https://learn.microsoft.com/en-us/azure/aks/csi-storage-drivers) - [Azure RedHat OpenShift](https://docs.openshift.com/container-platform/4.11/storage/container_storage_interface/persistent-storage-csi-azure-file.html) From ba00fe9593b9611c83bae8ede2bd1e48365808eb Mon Sep 17 00:00:00 2001 From: weizhichen Date: Wed, 8 Feb 2023 09:16:19 +0000 Subject: [PATCH 010/109] fix: switch base image to fix CVEs --- pkg/azurefileplugin/Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/azurefileplugin/Dockerfile b/pkg/azurefileplugin/Dockerfile index 884ddf1968..547a3576f6 100644 --- a/pkg/azurefileplugin/Dockerfile +++ b/pkg/azurefileplugin/Dockerfile @@ -12,13 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM registry.k8s.io/build-image/debian-base:bullseye-v1.4.2 +FROM alpine:3.15.1 ARG ARCH=amd64 ARG binary=./_output/${ARCH}/azurefileplugin COPY ${binary} /azurefileplugin -RUN apt update && apt upgrade -y && apt-mark unhold libcap2 && clean-install ca-certificates cifs-utils util-linux e2fsprogs mount udev xfsprogs nfs-common netbase +RUN apk upgrade --available --no-cache && \ + apk add --no-cache ca-certificates cifs-utils util-linux e2fsprogs-extra udev xfsprogs-extra nfs-utils LABEL maintainers="andyzhangx" LABEL description="AzureFile CSI Driver" From fafb587fd6d27d571084295ccc2e58a11bbc124d Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Thu, 9 Feb 2023 01:45:05 +0000 Subject: [PATCH 011/109] fix: buildx issue with provenance disabled --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index ae0d8c8964..ea4fb0f30f 100755 --- a/Makefile +++ b/Makefile @@ -134,12 +134,14 @@ container: azurefile .PHONY: container-linux container-linux: docker buildx build --pull --output=type=$(OUTPUT_TYPE) --platform="linux/$(ARCH)" \ + --provenance=false --sbom=false \ -t $(IMAGE_TAG)-linux-$(ARCH) --build-arg ARCH=${ARCH} -f ./pkg/azurefileplugin/Dockerfile . .PHONY: container-windows container-windows: docker buildx build --pull --output=type=$(OUTPUT_TYPE) --platform="windows/$(ARCH)" \ -t $(IMAGE_TAG)-windows-$(OSVERSION)-$(ARCH) --build-arg OSVERSION=$(OSVERSION) \ + --provenance=false --sbom=false \ --build-arg ARCH=${ARCH} -f ./pkg/azurefileplugin/Windows.Dockerfile . .PHONY: container-all From b312f89fb1f661bbf9ac17d059324afd18f78ffa Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Thu, 9 Feb 2023 01:50:07 +0000 Subject: [PATCH 012/109] test: fix externeal e2e test failure --- test/external-e2e/run.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/external-e2e/run.sh b/test/external-e2e/run.sh index 4190761528..678c5ed3b8 100644 --- a/test/external-e2e/run.sh +++ b/test/external-e2e/run.sh @@ -20,8 +20,7 @@ PROJECT_ROOT=$(git rev-parse --show-toplevel) DRIVER="test" install_ginkgo () { - apt update -y - apt install -y golang-ginkgo-dev + go install github.com/onsi/ginkgo/ginkgo@v1.14.0 } setup_e2e_binaries() { From e132a16f1fb9f8638454b123619113eb1a36e412 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Thu, 9 Feb 2023 02:00:52 +0000 Subject: [PATCH 013/109] test: set python3 in script --- hack/boilerplate/boilerplate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/boilerplate/boilerplate.py b/hack/boilerplate/boilerplate.py index 553bdee84d..5db7f571d6 100755 --- a/hack/boilerplate/boilerplate.py +++ b/hack/boilerplate/boilerplate.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2019 The Kubernetes Authors. # From cc001064372e5bff133b398e54a3068f863363ca Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Thu, 9 Feb 2023 11:57:14 +0000 Subject: [PATCH 014/109] chore: remove dependency on golang.org/x/text specific version --- go.mod | 3 +- go.sum | 15 ++++++- .../internal/language/compact/language.go | 2 +- .../x/text/internal/language/language.go | 2 +- .../x/text/internal/language/lookup.go | 2 +- vendor/golang.org/x/text/language/go1_1.go | 39 ------------------- vendor/golang.org/x/text/language/go1_2.go | 12 ------ vendor/golang.org/x/text/language/language.go | 2 +- vendor/golang.org/x/text/language/parse.go | 3 +- vendor/golang.org/x/text/runes/runes.go | 2 +- .../golang.org/x/text/unicode/bidi/trieval.go | 12 ------ vendor/modules.txt | 3 +- 12 files changed, 22 insertions(+), 75 deletions(-) delete mode 100644 vendor/golang.org/x/text/language/go1_1.go delete mode 100644 vendor/golang.org/x/text/language/go1_2.go diff --git a/go.mod b/go.mod index 90003fe2b1..795b7627fc 100644 --- a/go.mod +++ b/go.mod @@ -116,7 +116,7 @@ require ( golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect golang.org/x/sys v0.4.0 // indirect golang.org/x/term v0.4.0 // indirect - golang.org/x/text v0.6.0 // indirect + golang.org/x/text v0.7.0 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect @@ -138,7 +138,6 @@ replace ( github.com/niemeyer/pretty => github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e github.com/onsi/ginkgo/v2 => github.com/onsi/ginkgo/v2 v2.4.0 go.etcd.io/etcd => go.etcd.io/etcd v0.0.0-20200410171415-59f5fb25a533 - golang.org/x/text => golang.org/x/text v0.3.8 k8s.io/api => k8s.io/api v0.26.0 k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.26.0 k8s.io/apimachinery => k8s.io/apimachinery v0.26.0 diff --git a/go.sum b/go.sum index e3229a0a22..a8dbef4d60 100644 --- a/go.sum +++ b/go.sum @@ -640,14 +640,25 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= -golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= diff --git a/vendor/golang.org/x/text/internal/language/compact/language.go b/vendor/golang.org/x/text/internal/language/compact/language.go index 83816a72a8..8c1b6666fb 100644 --- a/vendor/golang.org/x/text/internal/language/compact/language.go +++ b/vendor/golang.org/x/text/internal/language/compact/language.go @@ -118,7 +118,7 @@ func (t Tag) Parent() Tag { return Tag{language: lang, locale: lang} } -// returns token t and the rest of the string. +// nextToken returns token t and the rest of the string. func nextToken(s string) (t, tail string) { p := strings.Index(s[1:], "-") if p == -1 { diff --git a/vendor/golang.org/x/text/internal/language/language.go b/vendor/golang.org/x/text/internal/language/language.go index 6105bc7fad..09d41c7367 100644 --- a/vendor/golang.org/x/text/internal/language/language.go +++ b/vendor/golang.org/x/text/internal/language/language.go @@ -409,7 +409,7 @@ func (t Tag) SetTypeForKey(key, value string) (Tag, error) { return t, nil } -// findKeyAndType returns the start and end position for the type corresponding +// findTypeForKey returns the start and end position for the type corresponding // to key or the point at which to insert the key-value pair if the type // wasn't found. The hasExt return value reports whether an -u extension was present. // Note: the extensions are typically very small and are likely to contain diff --git a/vendor/golang.org/x/text/internal/language/lookup.go b/vendor/golang.org/x/text/internal/language/lookup.go index 9309dc276a..231b4fbdeb 100644 --- a/vendor/golang.org/x/text/internal/language/lookup.go +++ b/vendor/golang.org/x/text/internal/language/lookup.go @@ -50,7 +50,7 @@ func (id Language) Canonicalize() (Language, AliasType) { return normLang(id) } -// mapLang returns the mapped langID of id according to mapping m. +// normLang returns the mapped langID of id according to mapping m. func normLang(id Language) (Language, AliasType) { k := sort.Search(len(AliasMap), func(i int) bool { return AliasMap[i].From >= uint16(id) diff --git a/vendor/golang.org/x/text/language/go1_1.go b/vendor/golang.org/x/text/language/go1_1.go deleted file mode 100644 index c7435583b5..0000000000 --- a/vendor/golang.org/x/text/language/go1_1.go +++ /dev/null @@ -1,39 +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. - -//go:build !go1.2 -// +build !go1.2 - -package language - -import "sort" - -func sortStable(s sort.Interface) { - ss := stableSort{ - s: s, - pos: make([]int, s.Len()), - } - for i := range ss.pos { - ss.pos[i] = i - } - sort.Sort(&ss) -} - -type stableSort struct { - s sort.Interface - pos []int -} - -func (s *stableSort) Len() int { - return len(s.pos) -} - -func (s *stableSort) Less(i, j int) bool { - return s.s.Less(i, j) || !s.s.Less(j, i) && s.pos[i] < s.pos[j] -} - -func (s *stableSort) Swap(i, j int) { - s.s.Swap(i, j) - s.pos[i], s.pos[j] = s.pos[j], s.pos[i] -} diff --git a/vendor/golang.org/x/text/language/go1_2.go b/vendor/golang.org/x/text/language/go1_2.go deleted file mode 100644 index 77aaaa299e..0000000000 --- a/vendor/golang.org/x/text/language/go1_2.go +++ /dev/null @@ -1,12 +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. - -//go:build go1.2 -// +build go1.2 - -package language - -import "sort" - -var sortStable = sort.Stable diff --git a/vendor/golang.org/x/text/language/language.go b/vendor/golang.org/x/text/language/language.go index 289b3a36d5..4d9c661212 100644 --- a/vendor/golang.org/x/text/language/language.go +++ b/vendor/golang.org/x/text/language/language.go @@ -344,7 +344,7 @@ func (t Tag) Parent() Tag { return Tag(compact.Tag(t).Parent()) } -// returns token t and the rest of the string. +// nextToken returns token t and the rest of the string. func nextToken(s string) (t, tail string) { p := strings.Index(s[1:], "-") if p == -1 { diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go index b982d9e422..4d57222e77 100644 --- a/vendor/golang.org/x/text/language/parse.go +++ b/vendor/golang.org/x/text/language/parse.go @@ -6,6 +6,7 @@ package language import ( "errors" + "sort" "strconv" "strings" @@ -206,7 +207,7 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { tag = append(tag, t) q = append(q, float32(w)) } - sortStable(&tagSort{tag, q}) + sort.Stable(&tagSort{tag, q}) return tag, q, nil } diff --git a/vendor/golang.org/x/text/runes/runes.go b/vendor/golang.org/x/text/runes/runes.go index 71933696f5..930e87fedb 100644 --- a/vendor/golang.org/x/text/runes/runes.go +++ b/vendor/golang.org/x/text/runes/runes.go @@ -33,7 +33,7 @@ func In(rt *unicode.RangeTable) Set { return setFunc(func(r rune) bool { return unicode.Is(rt, r) }) } -// In creates a Set with a Contains method that returns true for all runes not +// NotIn creates a Set with a Contains method that returns true for all runes not // in the given RangeTable. func NotIn(rt *unicode.RangeTable) Set { return setFunc(func(r rune) bool { return !unicode.Is(rt, r) }) diff --git a/vendor/golang.org/x/text/unicode/bidi/trieval.go b/vendor/golang.org/x/text/unicode/bidi/trieval.go index 4c459c4b72..6a796e2214 100644 --- a/vendor/golang.org/x/text/unicode/bidi/trieval.go +++ b/vendor/golang.org/x/text/unicode/bidi/trieval.go @@ -37,18 +37,6 @@ const ( unknownClass = ^Class(0) ) -var controlToClass = map[rune]Class{ - 0x202D: LRO, // LeftToRightOverride, - 0x202E: RLO, // RightToLeftOverride, - 0x202A: LRE, // LeftToRightEmbedding, - 0x202B: RLE, // RightToLeftEmbedding, - 0x202C: PDF, // PopDirectionalFormat, - 0x2066: LRI, // LeftToRightIsolate, - 0x2067: RLI, // RightToLeftIsolate, - 0x2068: FSI, // FirstStrongIsolate, - 0x2069: PDI, // PopDirectionalIsolate, -} - // A trie entry has the following bits: // 7..5 XOR mask for brackets // 4 1: Bracket open, 0: Bracket close diff --git a/vendor/modules.txt b/vendor/modules.txt index 72d71b1495..49d2166e1b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -474,7 +474,7 @@ golang.org/x/sys/windows/registry # golang.org/x/term v0.4.0 ## explicit; go 1.17 golang.org/x/term -# golang.org/x/text v0.6.0 => golang.org/x/text v0.3.8 +# golang.org/x/text v0.7.0 ## explicit; go 1.17 golang.org/x/text/encoding golang.org/x/text/encoding/charmap @@ -1298,7 +1298,6 @@ sigs.k8s.io/yaml # github.com/niemeyer/pretty => github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e # github.com/onsi/ginkgo/v2 => github.com/onsi/ginkgo/v2 v2.4.0 # go.etcd.io/etcd => go.etcd.io/etcd v0.0.0-20200410171415-59f5fb25a533 -# golang.org/x/text => golang.org/x/text v0.3.8 # k8s.io/api => k8s.io/api v0.26.0 # k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.26.0 # k8s.io/apimachinery => k8s.io/apimachinery v0.26.0 From 531058e109d2df4748c8710981e0c4d9fcb62e28 Mon Sep 17 00:00:00 2001 From: Andy Zhang Date: Thu, 9 Feb 2023 21:00:14 +0800 Subject: [PATCH 015/109] Update csi-debug.md --- docs/csi-debug.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/csi-debug.md b/docs/csi-debug.md index 3ddf69a2b3..d6c2f34472 100644 --- a/docs/csi-debug.md +++ b/docs/csi-debug.md @@ -81,7 +81,7 @@ kubectl edit ds csi-azurefile-node -n kube-system ``` change below deployment config, e.g. ```console - image: mcr.microsoft.com/k8s/csi/azurefile-csi:v1.5.0 + image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.24.0 imagePullPolicy: Always ``` @@ -152,7 +152,7 @@ mkdir /tmp/test mount -v -t nfs -o vers=4,minorversion=1,sec=sys accountname.file.core.windows.net:/accountname/filesharename /tmp/test ``` - - [Troubleshoot Azure File mount issues on AKS](https://docs.microsoft.com/en-us/troubleshoot/azure/azure-kubernetes/fail-to-mount-azure-file-share) + - [Troubleshoot Azure File mount issues on AKS](http://aka.ms/filemounterror) ### Troubleshooting performance issues on Azure Files From 23d363e96b9ba4f657a8e8ee256875e4b3c1cc7d Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Thu, 9 Feb 2023 12:47:13 +0000 Subject: [PATCH 016/109] feat: append help link when there is mount error doc: rephrase --- pkg/azurefile/azurefile.go | 3 +++ pkg/azurefile/nodeserver.go | 6 +++++- pkg/azurefileplugin/main.go | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/pkg/azurefile/azurefile.go b/pkg/azurefile/azurefile.go index eee1a79dcd..b888287019 100644 --- a/pkg/azurefile/azurefile.go +++ b/pkg/azurefile/azurefile.go @@ -192,6 +192,7 @@ type DriverOptions struct { AllowInlineVolumeKeyAccessWithIdentity bool EnableVHDDiskFeature bool EnableGetVolumeStats bool + AppendMountErrorHelpLink bool MountPermissions uint64 FSGroupChangePolicy string KubeAPIQPS float64 @@ -211,6 +212,7 @@ type Driver struct { allowInlineVolumeKeyAccessWithIdentity bool enableVHDDiskFeature bool enableGetVolumeStats bool + appendMountErrorHelpLink bool mountPermissions uint64 kubeAPIQPS float64 kubeAPIBurst int @@ -254,6 +256,7 @@ func NewDriver(options *DriverOptions) *Driver { driver.allowInlineVolumeKeyAccessWithIdentity = options.AllowInlineVolumeKeyAccessWithIdentity driver.enableVHDDiskFeature = options.EnableVHDDiskFeature driver.enableGetVolumeStats = options.EnableGetVolumeStats + driver.appendMountErrorHelpLink = options.AppendMountErrorHelpLink driver.mountPermissions = options.MountPermissions driver.fsGroupChangePolicy = options.FSGroupChangePolicy driver.kubeAPIQPS = options.KubeAPIQPS diff --git a/pkg/azurefile/nodeserver.go b/pkg/azurefile/nodeserver.go index 8633efa323..28a20c3779 100644 --- a/pkg/azurefile/nodeserver.go +++ b/pkg/azurefile/nodeserver.go @@ -318,7 +318,11 @@ func (d *Driver) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRe if err := wait.PollImmediate(1*time.Second, 2*time.Minute, func() (bool, error) { return true, SMBMount(d.mounter, source, cifsMountPath, mountFsType, mountOptions, sensitiveMountOptions) }); err != nil { - return nil, status.Error(codes.Internal, fmt.Sprintf("volume(%s) mount %s on %s failed with %v", volumeID, source, cifsMountPath, err)) + var helpLinkMsg string + if d.appendMountErrorHelpLink { + helpLinkMsg = fmt.Sprintf("\nPlease refer to http://aka.ms/filemounterror for possible causes and solutions for mount errors.") + } + return nil, status.Error(codes.Internal, fmt.Sprintf("volume(%s) mount %s on %s failed with %v%s", volumeID, source, cifsMountPath, err, helpLinkMsg)) } if protocol == nfs { if performChmodOp { diff --git a/pkg/azurefileplugin/main.go b/pkg/azurefileplugin/main.go index 19ae1e2ad7..146ee02a40 100644 --- a/pkg/azurefileplugin/main.go +++ b/pkg/azurefileplugin/main.go @@ -54,6 +54,7 @@ var ( enableVHDDiskFeature = flag.Bool("enable-vhd", true, "enable VHD disk feature (experimental)") kubeAPIQPS = flag.Float64("kube-api-qps", 25.0, "QPS to use while communicating with the kubernetes apiserver.") kubeAPIBurst = flag.Int("kube-api-burst", 50, "Burst to use while communicating with the kubernetes apiserver.") + appendMountErrorHelpLink = flag.Bool("append-mount-error-help-link", true, "Whether to include a link for help with mount errors when a mount error occurs.") ) func main() { @@ -91,6 +92,7 @@ func handle() { AllowInlineVolumeKeyAccessWithIdentity: *allowInlineVolumeKeyAccessWithIdentity, FSGroupChangePolicy: *fsGroupChangePolicy, EnableVHDDiskFeature: *enableVHDDiskFeature, + AppendMountErrorHelpLink: *appendMountErrorHelpLink, KubeAPIQPS: *kubeAPIQPS, KubeAPIBurst: *kubeAPIBurst, } From 1d753faba921df5149428488d16b5cb2293300ea Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Fri, 10 Feb 2023 02:48:35 +0000 Subject: [PATCH 017/109] doc: cut v1.26.0 release --- README.md | 2 +- charts/README.md | 2 +- charts/index.yaml | 83 ++- charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 11435 -> 0 bytes .../latest/azurefile-csi-driver-v1.26.0.tgz | Bin 0 -> 11417 bytes charts/latest/azurefile-csi-driver/Chart.yaml | 4 +- .../latest/azurefile-csi-driver/values.yaml | 4 +- .../v1.26.0/azurefile-csi-driver-v1.26.0.tgz | Bin 0 -> 11418 bytes .../v1.26.0/azurefile-csi-driver/Chart.yaml | 5 + .../azurefile-csi-driver/templates/NOTES.txt | 5 + .../templates/_helpers.tpl | 49 ++ .../templates/crd-csi-snapshot.yaml | 661 ++++++++++++++++++ .../templates/csi-azurefile-controller.yaml | 243 +++++++ .../templates/csi-azurefile-driver.yaml | 17 + .../templates/csi-azurefile-node-windows.yaml | 222 ++++++ .../templates/csi-azurefile-node.yaml | 217 ++++++ .../templates/csi-snapshot-controller.yaml | 65 ++ .../rbac-csi-azurefile-controller.yaml | 207 ++++++ .../templates/rbac-csi-azurefile-node.yaml | 29 + .../rbac-csi-snapshot-controller.yaml | 80 +++ ...rviceaccount-csi-azurefile-controller.yaml | 9 + .../serviceaccount-csi-azurefile-node.yaml | 9 + ...erviceaccount-csi-snapshot-controller.yaml | 9 + .../v1.26.0/azurefile-csi-driver/values.yaml | 254 +++++++ deploy/csi-azurefile-controller.yaml | 2 +- deploy/csi-azurefile-driver.yaml | 2 +- deploy/csi-azurefile-node-windows.yaml | 2 +- deploy/csi-azurefile-node.yaml | 2 +- deploy/v1.26.0/crd-csi-snapshot.yaml | 659 +++++++++++++++++ deploy/v1.26.0/csi-azurefile-controller.yaml | 184 +++++ deploy/v1.26.0/csi-azurefile-driver.yaml | 15 + .../v1.26.0/csi-azurefile-node-windows.yaml | 181 +++++ deploy/v1.26.0/csi-azurefile-node.yaml | 157 +++++ deploy/v1.26.0/csi-snapshot-controller.yaml | 46 ++ .../rbac-csi-azurefile-controller.yaml | 194 +++++ deploy/v1.26.0/rbac-csi-azurefile-node.yaml | 30 + .../v1.26.0/rbac-csi-snapshot-controller.yaml | 78 +++ docs/install-azurefile-csi-driver.md | 2 +- docs/install-csi-driver-v1.26.0.md | 45 ++ 39 files changed, 3727 insertions(+), 48 deletions(-) delete mode 100644 charts/latest/azurefile-csi-driver-v0.0.0.tgz create mode 100644 charts/latest/azurefile-csi-driver-v1.26.0.tgz create mode 100644 charts/v1.26.0/azurefile-csi-driver-v1.26.0.tgz create mode 100644 charts/v1.26.0/azurefile-csi-driver/Chart.yaml create mode 100644 charts/v1.26.0/azurefile-csi-driver/templates/NOTES.txt create mode 100644 charts/v1.26.0/azurefile-csi-driver/templates/_helpers.tpl create mode 100644 charts/v1.26.0/azurefile-csi-driver/templates/crd-csi-snapshot.yaml create mode 100644 charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-controller.yaml create mode 100644 charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-driver.yaml create mode 100644 charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml create mode 100644 charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-node.yaml create mode 100644 charts/v1.26.0/azurefile-csi-driver/templates/csi-snapshot-controller.yaml create mode 100644 charts/v1.26.0/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml create mode 100644 charts/v1.26.0/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml create mode 100644 charts/v1.26.0/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml create mode 100644 charts/v1.26.0/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml create mode 100644 charts/v1.26.0/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml create mode 100644 charts/v1.26.0/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml create mode 100644 charts/v1.26.0/azurefile-csi-driver/values.yaml create mode 100644 deploy/v1.26.0/crd-csi-snapshot.yaml create mode 100644 deploy/v1.26.0/csi-azurefile-controller.yaml create mode 100644 deploy/v1.26.0/csi-azurefile-driver.yaml create mode 100644 deploy/v1.26.0/csi-azurefile-node-windows.yaml create mode 100644 deploy/v1.26.0/csi-azurefile-node.yaml create mode 100644 deploy/v1.26.0/csi-snapshot-controller.yaml create mode 100644 deploy/v1.26.0/rbac-csi-azurefile-controller.yaml create mode 100644 deploy/v1.26.0/rbac-csi-azurefile-node.yaml create mode 100644 deploy/v1.26.0/rbac-csi-snapshot-controller.yaml create mode 100644 docs/install-csi-driver-v1.26.0.md diff --git a/README.md b/README.md index 02ed733d27..c13994114e 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,9 @@ Disclaimer: Deploying this driver manually is not an officially supported Micros |Driver Version |Image | supported k8s version | |----------------|---------------------------------------------------------- |-----------------------| |master branch |mcr.microsoft.com/k8s/csi/azurefile-csi:latest | 1.21+ | +|v1.26.0 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.0 | 1.21+ | |v1.25.1 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.25.1 | 1.21+ | |v1.24.0 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.24.0 | 1.21+ | -|v1.23.0 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.23.0 | 1.21+ | ### Driver parameters Please refer to [driver parameters](./docs/driver-parameters.md) diff --git a/charts/README.md b/charts/README.md index 2ca5f62d13..b2ff7adb29 100644 --- a/charts/README.md +++ b/charts/README.md @@ -16,7 +16,7 @@ ### install a specific version ```console helm repo add azurefile-csi-driver https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts -helm install azurefile-csi-driver azurefile-csi-driver/azurefile-csi-driver --namespace kube-system --version v1.25.1 +helm install azurefile-csi-driver azurefile-csi-driver/azurefile-csi-driver --namespace kube-system --version v1.26.0 ``` ### install on RedHat/CentOS diff --git a/charts/index.yaml b/charts/index.yaml index e1b74c5e16..7686add942 100644 --- a/charts/index.yaml +++ b/charts/index.yaml @@ -1,9 +1,27 @@ apiVersion: v1 entries: azurefile-csi-driver: + - apiVersion: v1 + appVersion: v1.26.0 + created: "2023-02-10T02:47:55.453528262Z" + description: Azure File Container Storage Interface (CSI) Storage Plugin + digest: 71f843ca5c1bf23cf484eaa404dfb27c6f9d614a7b4d672331dd8c9fe36ced06 + name: azurefile-csi-driver + urls: + - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/latest/azurefile-csi-driver-v1.26.0.tgz + version: v1.26.0 + - apiVersion: v1 + appVersion: v1.26.0 + created: "2023-02-10T02:47:55.50942039Z" + description: Azure File Container Storage Interface (CSI) Storage Plugin + digest: 98d15a8ced671a7c3d9aec8ebe00b58abeecb5f65ab966c9c01c4f39121adc0c + name: azurefile-csi-driver + urls: + - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/v1.26.0/azurefile-csi-driver-v1.26.0.tgz + version: v1.26.0 - apiVersion: v1 appVersion: v1.25.1 - created: "2023-01-18T08:03:41.908826298Z" + created: "2023-02-10T02:47:55.508434805Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 2bf374cc321c5bc8e76e06cd5df85ce7d7d14574397e7e7f7173077393f554c4 name: azurefile-csi-driver @@ -12,7 +30,7 @@ entries: version: v1.25.1 - apiVersion: v1 appVersion: v1.25.0 - created: "2023-01-18T08:03:41.906575576Z" + created: "2023-02-10T02:47:55.507255598Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: ba80dcd23dade4e62b39d3dc638c599e9d5e100009fa14d4164bfc8966fea3dd name: azurefile-csi-driver @@ -21,7 +39,7 @@ entries: version: v1.25.0 - apiVersion: v1 appVersion: v1.24.0 - created: "2023-01-18T08:03:41.905098661Z" + created: "2023-02-10T02:47:55.502796536Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 1905eb862745d4a7f57c5de96848cee194adf827086984b75bcaefce5c90142b name: azurefile-csi-driver @@ -30,7 +48,7 @@ entries: version: v1.24.0 - apiVersion: v1 appVersion: v1.23.0 - created: "2023-01-18T08:03:41.903343544Z" + created: "2023-02-10T02:47:55.498925196Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 5fcb33617d16e90df1e7041b0df02e5bd92595e86381db30d356b0b2e3500bc4 name: azurefile-csi-driver @@ -39,7 +57,7 @@ entries: version: v1.23.0 - apiVersion: v1 appVersion: v1.22.0 - created: "2023-01-18T08:03:41.901897329Z" + created: "2023-02-10T02:47:55.496694137Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 253d87a8b876dbdd55870a7fee88547393179d03f193661125f5a0b63411f922 name: azurefile-csi-driver @@ -48,7 +66,7 @@ entries: version: v1.22.0 - apiVersion: v1 appVersion: v1.21.0 - created: "2023-01-18T08:03:41.900301813Z" + created: "2023-02-10T02:47:55.495570131Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: d45bf3455ebadc9cc5afaf9da66aa1ea1d4b719cfdff5af661f93bb26c01a504 name: azurefile-csi-driver @@ -57,7 +75,7 @@ entries: version: v1.21.0 - apiVersion: v1 appVersion: v1.20.0 - created: "2023-01-18T08:03:41.89805449Z" + created: "2023-02-10T02:47:55.494479748Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 7cc43d57a79137aea5414fb51a9bbd77bb679b29ee49c06865c1a5b9ba60be99 name: azurefile-csi-driver @@ -66,7 +84,7 @@ entries: version: v1.20.0 - apiVersion: v1 appVersion: v1.19.0 - created: "2023-01-18T08:03:41.896063471Z" + created: "2023-02-10T02:47:55.487060353Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 18f6efbed424efd661fde43be2e5a48a5012a46a7938c33b36963cbd9875a5af name: azurefile-csi-driver @@ -75,7 +93,7 @@ entries: version: v1.19.0 - apiVersion: v1 appVersion: v1.18.0 - created: "2023-01-18T08:03:41.894651456Z" + created: "2023-02-10T02:47:55.485989416Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 696ca23d9ee517f71ef5e852955c8d0f1017c331c025426c6fcbe7a06d006c66 name: azurefile-csi-driver @@ -84,7 +102,7 @@ entries: version: v1.18.0 - apiVersion: v1 appVersion: v1.17.0 - created: "2023-01-18T08:03:41.893267042Z" + created: "2023-02-10T02:47:55.484076077Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 5632f61265a3b78dce3e2b15e07cc9b14a7f54a778878c02ca2d9fe69ca0344e name: azurefile-csi-driver @@ -93,7 +111,7 @@ entries: version: v1.17.0 - apiVersion: v1 appVersion: v1.16.0 - created: "2023-01-18T08:03:41.89199333Z" + created: "2023-02-10T02:47:55.482981458Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: a7a2d57e8eca7dc06c8b2cffb9bccb857753eb110b8e70760b3e04f4e6a87552 name: azurefile-csi-driver @@ -102,7 +120,7 @@ entries: version: v1.16.0 - apiVersion: v1 appVersion: v1.15.0 - created: "2023-01-18T08:03:41.889838908Z" + created: "2023-02-10T02:47:55.479494726Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: c1a31dadce233a90c19dce70f6cc92ba2e20bbaa1b1883baea72381d09303118 name: azurefile-csi-driver @@ -111,7 +129,7 @@ entries: version: v1.15.0 - apiVersion: v1 appVersion: v1.14.0 - created: "2023-01-18T08:03:41.888541195Z" + created: "2023-02-10T02:47:55.478417345Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 0c9ad4afa5ebfdb2851ad93eb16a0382d61448714b7556899360730a2fdf463a name: azurefile-csi-driver @@ -120,7 +138,7 @@ entries: version: v1.14.0 - apiVersion: v1 appVersion: v1.13.0 - created: "2023-01-18T08:03:41.887146481Z" + created: "2023-02-10T02:47:55.47472126Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 214042b029d858b50a0f8bba33a7aa2b41d1b67bce16f957ca183ae7438dac3f name: azurefile-csi-driver @@ -129,7 +147,7 @@ entries: version: v1.13.0 - apiVersion: v1 appVersion: v1.12.0 - created: "2023-01-18T08:03:41.885874068Z" + created: "2023-02-10T02:47:55.470657536Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: fbd63929671066a26df898d32282a6e79c39499a39c71761c546d069459d847d name: azurefile-csi-driver @@ -138,7 +156,7 @@ entries: version: v1.12.0 - apiVersion: v1 appVersion: v1.11.0 - created: "2023-01-18T08:03:41.884300753Z" + created: "2023-02-10T02:47:55.466080724Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 76bd438f8391d08235b09fbca859f25a9fcf8e018fd1e7e33444ca9ea946ce4b name: azurefile-csi-driver @@ -147,7 +165,7 @@ entries: version: v1.11.0 - apiVersion: v1 appVersion: v1.10.0 - created: "2023-01-18T08:03:41.881607826Z" + created: "2023-02-10T02:47:55.464087272Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 845a9de8b571b255d05ae9c643d9b90a57fe6507ff3fb735c88b41f99f6f28dc name: azurefile-csi-driver @@ -156,7 +174,7 @@ entries: version: v1.10.0 - apiVersion: v1 appVersion: v1.9.0 - created: "2023-01-18T08:03:41.917453285Z" + created: "2023-02-10T02:47:55.520423456Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 59a8057fbbd6d59919b84ef0c3396d5a0a46d1f29df604457db676f4af63c714 name: azurefile-csi-driver @@ -165,7 +183,7 @@ entries: version: v1.9.0 - apiVersion: v1 appVersion: v1.8.0 - created: "2023-01-18T08:03:41.91598967Z" + created: "2023-02-10T02:47:55.518304685Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 455b7c342194311046df526d10926d94f3bef24f753a07003fb1cad211c4cb52 name: azurefile-csi-driver @@ -174,7 +192,7 @@ entries: version: v1.8.0 - apiVersion: v1 appVersion: v1.7.0 - created: "2023-01-18T08:03:41.913636147Z" + created: "2023-02-10T02:47:55.517159805Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 057b3f6ef6001d3457fbffc27f90316c981a089696abd3d38bcc8de5537dfa6f name: azurefile-csi-driver @@ -183,7 +201,7 @@ entries: version: v1.7.0 - apiVersion: v1 appVersion: v1.6.0 - created: "2023-01-18T08:03:41.912616936Z" + created: "2023-02-10T02:47:55.516288668Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: cc2a0dda824cdda4e8141e26878bbb481c5a52e45785a5dbf72e54f2a376e522 name: azurefile-csi-driver @@ -192,7 +210,7 @@ entries: version: v1.6.0 - apiVersion: v1 appVersion: v1.5.0 - created: "2023-01-18T08:03:41.911505825Z" + created: "2023-02-10T02:47:55.515428634Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 2258177477415ddecd83dc46dfd88833223623224c7fe396590b617082bcd845 name: azurefile-csi-driver @@ -201,7 +219,7 @@ entries: version: v1.5.0 - apiVersion: v1 appVersion: v1.4.0 - created: "2023-01-18T08:03:41.910547616Z" + created: "2023-02-10T02:47:55.514592609Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 40e9bc4ee187789166fcb7c3c82b85b33ecd3a6096266fe74e411d6b48961ece name: azurefile-csi-driver @@ -210,7 +228,7 @@ entries: version: v1.4.0 - apiVersion: v1 appVersion: v1.3.0 - created: "2023-01-18T08:03:41.909586706Z" + created: "2023-02-10T02:47:55.511384373Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 12942f422b7cccbfe950bbdbd5c844f5ae4b7c292f32389cba312730a6fe9a62 name: azurefile-csi-driver @@ -219,7 +237,7 @@ entries: version: v1.3.0 - apiVersion: v1 appVersion: v1.2.0 - created: "2023-01-18T08:03:41.896767678Z" + created: "2023-02-10T02:47:55.490473708Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: b62f44b757416a9e1f5a91e19285f5f5056ec6068802dd9cd82373bef40c9ee9 name: azurefile-csi-driver @@ -228,7 +246,7 @@ entries: version: v1.2.0 - apiVersion: v1 appVersion: v1.1.0 - created: "2023-01-18T08:03:41.880325313Z" + created: "2023-02-10T02:47:55.462914131Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 675d96b309a1c5c491053ebbb854c046737420929c4f0692839afdaaf0db3933 name: azurefile-csi-driver @@ -237,20 +255,11 @@ entries: version: v1.1.0 - apiVersion: v1 appVersion: v1.0.0 - created: "2023-01-18T08:03:41.879587105Z" + created: "2023-02-10T02:47:55.457277198Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 6fd5e54e949ef1061a08d5477bc580204c91dde8f01da195e95dd60ade209492 name: azurefile-csi-driver urls: - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/v1.0.0/azurefile-csi-driver-v1.0.0.tgz version: v1.0.0 - - apiVersion: v1 - appVersion: latest - created: "2023-01-18T08:03:41.878783397Z" - description: Azure File Container Storage Interface (CSI) Storage Plugin - digest: 374f40b7c22c45f91b9557ffebede2be3d9dfc217e44a78d11e9fc76478ee28f - name: azurefile-csi-driver - urls: - - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/latest/azurefile-csi-driver-v0.0.0.tgz - version: v0.0.0 -generated: "2023-01-18T08:03:41.877114781Z" +generated: "2023-02-10T02:47:55.452013107Z" diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz deleted file mode 100644 index 965bb9451777081fcfee43c9d0dcf9794d6a795c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11435 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 z z(u_s&n75W3*-?A$8jZu)e$~_*_st*nx>GhZE`rzfb12-#HS}ET<$&hgtS;wm=EHRp zv9!!I?~Zn6KQ4`y#!@QV%*CeMX9jsRPQlLia-xVB*(!9NaCEzR(P z4P9$3z_t8NFyw_=5Fx;{XrXCALAyWuMRGO`MLk3~ZTx|SOK&xhk!2)Xcmk?3X|yTv zY9_B0Tt9zBCpeJ@X3B%HgZy;7{&xpNf_-iaC&10AmVK|=8tJ4t!8=vDzTd3J#@P3( zbnF`Fa$6cE)gmQYd+pAwZNbZsK`i|NJw)BK{@~}66LZUdMiZ?!K!qj%avPDiSaP&G z&go~w>xxxzF;a^o&r0_zDv!5Y2RlZ!X)xN^uDW(}?RZhu$gbl;k8Rx*01vf_d>kSf zOYaW4<_F*_=2rVCUfY`WkK{Ug`;f+7aI0^BxFQ32AKnXiAfzZA77Vs>?1=%}9nx)q z8DY{?EqfA*N>mmzuLHS9{-pPO0LQteYwt0KDTK~X0@kH(Og^?5w!pmK&#nUO4!t-( z6bB-6j)eCbJ3m=S5cG<{5pYBId3Y>_|6EO}mKiVGPqAV-!dn^9SEsrEzPun<_@4_I O{Pt*M1n~zF;{O0w+Q|O^ literal 0 HcmV?d00001 diff --git a/charts/latest/azurefile-csi-driver/Chart.yaml b/charts/latest/azurefile-csi-driver/Chart.yaml index 27ff7d757c..c30547c2df 100644 --- a/charts/latest/azurefile-csi-driver/Chart.yaml +++ b/charts/latest/azurefile-csi-driver/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: latest +appVersion: v1.26.0 description: Azure File Container Storage Interface (CSI) Storage Plugin name: azurefile-csi-driver -version: v0.0.0 +version: v1.26.0 diff --git a/charts/latest/azurefile-csi-driver/values.yaml b/charts/latest/azurefile-csi-driver/values.yaml index 50f8a7c731..043a5ad872 100644 --- a/charts/latest/azurefile-csi-driver/values.yaml +++ b/charts/latest/azurefile-csi-driver/values.yaml @@ -1,8 +1,8 @@ image: baseRepo: mcr.microsoft.com azurefile: - repository: /k8s/csi/azurefile-csi - tag: latest + repository: /oss/kubernetes-csi/azurefile-csi + tag: v1.26.0 pullPolicy: IfNotPresent csiProvisioner: repository: /oss/kubernetes-csi/csi-provisioner diff --git a/charts/v1.26.0/azurefile-csi-driver-v1.26.0.tgz b/charts/v1.26.0/azurefile-csi-driver-v1.26.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..086cc0f25fad1441b61b5f5a4e62620d15bafc76 GIT binary patch literal 11418 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 XUo3-fA)o$@Aw!-`9;BfvprQT;{O+Gd literal 0 HcmV?d00001 diff --git a/charts/v1.26.0/azurefile-csi-driver/Chart.yaml b/charts/v1.26.0/azurefile-csi-driver/Chart.yaml new file mode 100644 index 0000000000..c30547c2df --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +appVersion: v1.26.0 +description: Azure File Container Storage Interface (CSI) Storage Plugin +name: azurefile-csi-driver +version: v1.26.0 diff --git a/charts/v1.26.0/azurefile-csi-driver/templates/NOTES.txt b/charts/v1.26.0/azurefile-csi-driver/templates/NOTES.txt new file mode 100644 index 0000000000..3fadd8ad36 --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/templates/NOTES.txt @@ -0,0 +1,5 @@ +The Azure File CSI Driver is getting deployed to your cluster. + +To check Azure File CSI Driver pods status, please run: + + kubectl --namespace={{ .Release.Namespace }} get pods --selector="release={{ .Release.Name }}" --watch diff --git a/charts/v1.26.0/azurefile-csi-driver/templates/_helpers.tpl b/charts/v1.26.0/azurefile-csi-driver/templates/_helpers.tpl new file mode 100644 index 0000000000..b1bf4dc1b6 --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/templates/_helpers.tpl @@ -0,0 +1,49 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* Expand the name of the chart.*/}} +{{- define "azurefile.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "azurefile.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common selectors. +*/}} +{{- define "azurefile.selectorLabels" -}} +app.kubernetes.io/name: {{ template "azurefile.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Common labels. +*/}} +{{- define "azurefile.labels" -}} +{{- include "azurefile.selectorLabels" . }} +app.kubernetes.io/component: csi-driver +app.kubernetes.io/part-of: {{ template "azurefile.name" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +helm.sh/chart: {{ template "azurefile.chart" . }} +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels }} +{{- end }} +{{- end -}} + + +{{/* pull secrets for containers */}} +{{- define "azurefile.pullSecrets" -}} +{{- if .Values.imagePullSecrets }} +imagePullSecrets: +{{- range .Values.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} +{{- end -}} diff --git a/charts/v1.26.0/azurefile-csi-driver/templates/crd-csi-snapshot.yaml b/charts/v1.26.0/azurefile-csi-driver/templates/crd-csi-snapshot.yaml new file mode 100644 index 0000000000..b0e29453c5 --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/templates/crd-csi-snapshot.yaml @@ -0,0 +1,661 @@ +{{- if .Values.snapshot.enabled -}} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + creationTimestamp: null + name: volumesnapshots.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshot + listKind: VolumeSnapshotList + plural: volumesnapshots + shortNames: + - vs + singular: volumesnapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' + properties: + source: + description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. + type: string + type: object + oneOf: + - required: ["persistentVolumeClaimName"] + - required: ["volumeSnapshotContentName"] + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurrs during the snapshot creation. Upon success, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + type: string + description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshot is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshot" + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' + properties: + source: + description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurrs during the snapshot creation. Upon success, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + type: string + description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + creationTimestamp: null + name: volumesnapshotclasses.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotClass + listKind: VolumeSnapshotClassList + plural: volumesnapshotclasses + shortNames: + - vsclass + - vsclasses + singular: volumesnapshotclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotClass is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotClass" + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + creationTimestamp: null + name: volumesnapshotcontents.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotContent + listKind: VolumeSnapshotContentList + plural: volumesnapshotcontents + shortNames: + - vsc + - vscs + singular: volumesnapshotcontent + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. + type: string + type: object + oneOf: + - required: ["snapshotHandle"] + - required: ["volumeHandle"] + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotContent is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotContent" + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. + type: string + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-controller.yaml b/charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-controller.yaml new file mode 100644 index 0000000000..23381ec245 --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-controller.yaml @@ -0,0 +1,243 @@ +kind: Deployment +apiVersion: apps/v1 +metadata: + name: {{ .Values.controller.name }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Values.controller.name }} + {{- include "azurefile.labels" . | nindent 4 }} +{{- with .Values.controller.labels }} +{{ . | toYaml | indent 4 }} +{{- end }} +{{- with .Values.controller.annotations }} + annotations: +{{ . | toYaml | indent 4 }} +{{- end }} +spec: + replicas: {{ .Values.controller.replicas }} + selector: + matchLabels: + {{- include "azurefile.selectorLabels" . | nindent 6 }} + app: {{ .Values.controller.name }} + template: + metadata: + labels: + {{- include "azurefile.labels" . | nindent 8 }} + app: {{ .Values.controller.name }} +{{- with .Values.controller.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.controller.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + spec: + hostNetwork: {{ .Values.controller.hostNetwork }} + serviceAccountName: {{ .Values.serviceAccount.controller }} + nodeSelector: + kubernetes.io/os: linux +{{- with .Values.controller.nodeSelector }} +{{ toYaml . | indent 8 }} +{{- end }} + {{- if .Values.controller.runOnMaster}} + node-role.kubernetes.io/master: "" + {{- end}} + {{- if .Values.controller.runOnControlPlane}} + node-role.kubernetes.io/control-plane: "" + {{- end}} + priorityClassName: system-cluster-critical +{{- with .Values.controller.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.controller.affinity }} + affinity: +{{ toYaml . | indent 8 }} +{{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + containers: + - name: csi-provisioner +{{- if hasPrefix "/" .Values.image.csiProvisioner.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.csiProvisioner.repository }}:{{ .Values.image.csiProvisioner.tag }}" +{{- else }} + image: "{{ .Values.image.csiProvisioner.repository }}:{{ .Values.image.csiProvisioner.tag }}" +{{- end }} + args: + - "-v=2" + - "--csi-address=$(ADDRESS)" + - "--leader-election" + - "--leader-election-namespace={{ .Release.Namespace }}" + - "--timeout=300s" + - "--extra-create-metadata=true" + - "--kube-api-qps=50" + - "--kube-api-burst=100" + env: + - name: ADDRESS + value: /csi/csi.sock + imagePullPolicy: {{ .Values.image.csiProvisioner.pullPolicy }} + volumeMounts: + - mountPath: /csi + name: socket-dir + resources: {{- toYaml .Values.controller.resources.csiProvisioner | nindent 12 }} + - name: csi-attacher +{{- if hasPrefix "/" .Values.image.csiAttacher.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.csiAttacher.repository }}:{{ .Values.image.csiAttacher.tag }}" +{{- else }} + image: "{{ .Values.image.csiAttacher.repository }}:{{ .Values.image.csiAttacher.tag }}" +{{- end }} + args: + - "-v=2" + - "-csi-address=$(ADDRESS)" + - "-timeout=120s" + - "-leader-election" + - "--leader-election-namespace={{ .Release.Namespace }}" + - "--kube-api-qps=50" + - "--kube-api-burst=100" + env: + - name: ADDRESS + value: /csi/csi.sock + imagePullPolicy: {{ .Values.image.csiAttacher.pullPolicy }} + volumeMounts: + - mountPath: /csi + name: socket-dir + resources: {{- toYaml .Values.controller.resources.csiAttacher | nindent 12 }} + - name: csi-snapshotter +{{- if hasPrefix "/" .Values.snapshot.image.csiSnapshotter.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.snapshot.image.csiSnapshotter.repository }}:{{ .Values.snapshot.image.csiSnapshotter.tag }}" +{{- else }} + image: "{{ .Values.snapshot.image.csiSnapshotter.repository }}:{{ .Values.snapshot.image.csiSnapshotter.tag }}" +{{- end }} + args: + - "-csi-address=$(ADDRESS)" + - "-leader-election" + - "--leader-election-namespace={{ .Release.Namespace }}" + - "-v=2" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /csi + resources: {{- toYaml .Values.controller.resources.csiSnapshotter | nindent 12 }} + - name: csi-resizer +{{- if hasPrefix "/" .Values.image.csiResizer.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.csiResizer.repository }}:{{ .Values.image.csiResizer.tag }}" +{{- else }} + image: "{{ .Values.image.csiResizer.repository }}:{{ .Values.image.csiResizer.tag }}" +{{- end }} + args: + - "-csi-address=$(ADDRESS)" + - "-v=2" + - "-leader-election" + - "--leader-election-namespace={{ .Release.Namespace }}" + - '-handle-volume-inuse-error=false' + - '-timeout=120s' + - '-feature-gates=RecoverVolumeExpansionFailure=true' + env: + - name: ADDRESS + value: /csi/csi.sock + imagePullPolicy: {{ .Values.image.csiResizer.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /csi + resources: {{- toYaml .Values.controller.resources.csiResizer | nindent 12 }} + - name: liveness-probe +{{- if hasPrefix "/" .Values.image.livenessProbe.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- else }} + image: "{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- end }} + args: + - --csi-address=/csi/csi.sock + - --probe-timeout=3s + - --health-port={{ .Values.controller.livenessProbe.healthPort }} + - --v=2 + imagePullPolicy: {{ .Values.image.livenessProbe.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /csi + resources: {{- toYaml .Values.controller.resources.livenessProbe | nindent 12 }} + - name: azurefile +{{- if hasPrefix "/" .Values.image.azurefile.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" +{{- else }} + image: "{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" +{{- end }} + args: + - "--v={{ .Values.controller.logLevel }}" + - "--endpoint=$(CSI_ENDPOINT)" + - "--metrics-address=0.0.0.0:{{ .Values.controller.metricsPort }}" + - "--kubeconfig={{ .Values.controller.kubeconfig }}" + - "--drivername={{ .Values.driver.name }}" + - "--cloud-config-secret-name={{ .Values.controller.cloudConfigSecretName }}" + - "--cloud-config-secret-namespace={{ .Values.controller.cloudConfigSecretNamespace }}" + - "--custom-user-agent={{ .Values.driver.customUserAgent }}" + - "--user-agent-suffix={{ .Values.driver.userAgentSuffix }}" + - "--allow-empty-cloud-config={{ .Values.controller.allowEmptyCloudConfig }}" + ports: + - containerPort: {{ .Values.controller.livenessProbe.healthPort }} + name: healthz + protocol: TCP + - containerPort: {{ .Values.controller.metricsPort }} + name: metrics + protocol: TCP + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + timeoutSeconds: 10 + periodSeconds: 30 + env: + - name: AZURE_CREDENTIAL_FILE + valueFrom: + configMapKeyRef: + name: azure-cred-file + key: path + optional: true + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + {{- if ne .Values.driver.httpsProxy "" }} + - name: HTTPS_PROXY + value: {{ .Values.driver.httpsProxy }} + {{- end }} + {{- if ne .Values.driver.httpProxy "" }} + - name: HTTP_PROXY + value: {{ .Values.driver.httpProxy }} + {{- end }} + - name: AZURE_GO_SDK_LOG_LEVEL + value: {{ .Values.driver.azureGoSDKLogLevel }} + imagePullPolicy: {{ .Values.image.azurefile.pullPolicy }} + volumeMounts: + - mountPath: /csi + name: socket-dir + - mountPath: /etc/kubernetes/ + name: azure-cred + {{- if eq .Values.linux.distro "fedora" }} + - name: ssl + mountPath: /etc/ssl/certs + readOnly: true + - name: ssl-pki + mountPath: /etc/pki/ca-trust/extracted + readOnly: true + {{- end }} + resources: {{- toYaml .Values.controller.resources.azurefile | nindent 12 }} + volumes: + - name: socket-dir + emptyDir: {} + - name: azure-cred + hostPath: + path: /etc/kubernetes/ + type: DirectoryOrCreate + {{- if eq .Values.linux.distro "fedora" }} + - name: ssl + hostPath: + path: /etc/ssl/certs + - name: ssl-pki + hostPath: + path: /etc/pki/ca-trust/extracted + {{- end }} diff --git a/charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-driver.yaml b/charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-driver.yaml new file mode 100644 index 0000000000..e1facb056a --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-driver.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: {{ .Values.driver.name }} + labels: + {{- include "azurefile.labels" . | nindent 4 }} + annotations: + csiDriver: "{{ .Values.image.azurefile.tag }}" + snapshot: "{{ .Values.snapshot.image.csiSnapshotter.tag }}" +spec: + attachRequired: {{ .Values.controller.attachRequired }} + podInfoOnMount: true + volumeLifecycleModes: + - Persistent + - Ephemeral + fsGroupPolicy: ReadWriteOnceWithFSType diff --git a/charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml b/charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml new file mode 100644 index 0000000000..813859aee0 --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml @@ -0,0 +1,222 @@ +{{- if .Values.windows.enabled}} +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: {{ .Values.windows.dsName }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Values.windows.dsName }} + {{- include "azurefile.labels" . | nindent 4 }} +{{- with .Values.windows.labels }} +{{ . | toYaml | indent 4 }} +{{- end }} +{{- with .Values.windows.annotations }} + annotations: +{{ . | toYaml | indent 4 }} +{{- end }} +spec: + updateStrategy: + rollingUpdate: + maxUnavailable: {{ .Values.node.maxUnavailable }} + type: RollingUpdate + selector: + matchLabels: + app: {{ .Values.windows.dsName }} + {{- include "azurefile.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + app: {{ .Values.windows.dsName }} + {{- include "azurefile.labels" . | nindent 8 }} +{{- with .Values.windows.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.windows.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + spec: + serviceAccountName: {{ .Values.serviceAccount.node }} +{{- with .Values.windows.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} +{{- end }} + nodeSelector: + kubernetes.io/os: windows +{{- with .Values.windows.nodeSelector }} +{{ toYaml . | indent 8 }} +{{- end }} + affinity: +{{- with .Values.windows.affinity }} +{{ toYaml . | indent 8 }} +{{- end }} + nodeAffinity: +{{ toYaml .Values.windows.nodeAffinity | indent 10 }} + priorityClassName: system-node-critical + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + containers: + - name: liveness-probe + volumeMounts: + - mountPath: C:\csi + name: plugin-dir +{{- if hasPrefix "/" .Values.image.livenessProbe.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- else }} + image: "{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- end }} + args: + - "--csi-address=$(CSI_ENDPOINT)" + - "--probe-timeout=3s" + - "--health-port={{ .Values.node.livenessProbe.healthPort }}" + - "--v=2" + env: + - name: CSI_ENDPOINT + value: unix://C:\\csi\\csi.sock + imagePullPolicy: {{ .Values.image.livenessProbe.pullPolicy }} + resources: {{- toYaml .Values.windows.resources.livenessProbe | nindent 12 }} + - name: node-driver-registrar +{{- if hasPrefix "/" .Values.image.nodeDriverRegistrar.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.nodeDriverRegistrar.repository }}:{{ .Values.image.nodeDriverRegistrar.tag }}" +{{- else }} + image: "{{ .Values.image.nodeDriverRegistrar.repository }}:{{ .Values.image.nodeDriverRegistrar.tag }}" +{{- end }} + args: + - "--csi-address=$(CSI_ENDPOINT)" + - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" + - "--v=2" + livenessProbe: + exec: + command: + - /csi-node-driver-registrar.exe + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --mode=kubelet-registration-probe + initialDelaySeconds: 60 + timeoutSeconds: 30 + env: + - name: CSI_ENDPOINT + value: unix://C:\\csi\\csi.sock + - name: DRIVER_REG_SOCK_PATH + value: C:\\var\\lib\\kubelet\\plugins\\{{ .Values.driver.name }}\\csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + imagePullPolicy: {{ .Values.image.nodeDriverRegistrar.pullPolicy }} + volumeMounts: + - name: kubelet-dir + mountPath: "C:\\var\\lib\\kubelet" + - name: plugin-dir + mountPath: C:\csi + - name: registration-dir + mountPath: C:\registration + resources: {{- toYaml .Values.windows.resources.nodeDriverRegistrar | nindent 12 }} + - name: azurefile +{{- if hasPrefix "/" .Values.image.azurefile.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" +{{- else }} + image: "{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" +{{- end }} + args: + - "--v={{ .Values.node.logLevel }}" + - "--endpoint=$(CSI_ENDPOINT)" + - "--nodeid=$(KUBE_NODE_NAME)" + - "--metrics-address=0.0.0.0:{{ .Values.node.metricsPort }}" + - "--kubeconfig={{ .Values.windows.kubeconfig }}" + - "--drivername={{ .Values.driver.name }}" + - "--cloud-config-secret-name={{ .Values.node.cloudConfigSecretName }}" + - "--cloud-config-secret-namespace={{ .Values.node.cloudConfigSecretNamespace }}" + - "--custom-user-agent={{ .Values.driver.customUserAgent }}" + - "--user-agent-suffix={{ .Values.driver.userAgentSuffix }}" + - "--allow-empty-cloud-config={{ .Values.node.allowEmptyCloudConfig }}" + - "--enable-get-volume-stats={{ .Values.feature.enableGetVolumeStats }}" + - "--allow-inline-volume-key-access-with-identity={{ .Values.node.allowInlineVolumeKeyAccessWithIdentity }}" + ports: + - containerPort: {{ .Values.node.livenessProbe.healthPort }} + name: healthz + protocol: TCP + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + timeoutSeconds: 10 + periodSeconds: 30 + env: + - name: AZURE_CREDENTIAL_FILE + valueFrom: + configMapKeyRef: + name: azure-cred-file + key: path-windows + optional: true + - name: CSI_ENDPOINT + value: unix://C:\\csi\\csi.sock + {{- if ne .Values.driver.httpsProxy "" }} + - name: HTTPS_PROXY + value: {{ .Values.driver.httpsProxy }} + {{- end }} + {{- if ne .Values.driver.httpProxy "" }} + - name: HTTP_PROXY + value: {{ .Values.driver.httpProxy }} + {{- end }} + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: AZURE_GO_SDK_LOG_LEVEL + value: {{ .Values.driver.azureGoSDKLogLevel }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + volumeMounts: + - name: kubelet-dir + mountPath: "C:\\var\\lib\\kubelet" + - name: plugin-dir + mountPath: C:\csi + - name: azure-config + mountPath: C:\k + - name: csi-proxy-fs-pipe-v1 + mountPath: \\.\pipe\csi-proxy-filesystem-v1 + - name: csi-proxy-smb-pipe-v1 + mountPath: \\.\pipe\csi-proxy-smb-v1 + # these paths are still included for compatibility, they're used + # only if the node has still the beta version of the CSI proxy + - name: csi-proxy-fs-pipe-v1beta1 + mountPath: \\.\pipe\csi-proxy-filesystem-v1beta1 + - name: csi-proxy-smb-pipe-v1beta1 + mountPath: \\.\pipe\csi-proxy-smb-v1beta1 + resources: {{- toYaml .Values.windows.resources.azurefile | nindent 12 }} + volumes: + - name: csi-proxy-fs-pipe-v1 + hostPath: + path: \\.\pipe\csi-proxy-filesystem-v1 + - name: csi-proxy-smb-pipe-v1 + hostPath: + path: \\.\pipe\csi-proxy-smb-v1 + # these paths are still included for compatibility, they're used + # only if the node has still the beta version of the CSI proxy + - name: csi-proxy-fs-pipe-v1beta1 + hostPath: + path: \\.\pipe\csi-proxy-filesystem-v1beta1 + - name: csi-proxy-smb-pipe-v1beta1 + hostPath: + path: \\.\pipe\csi-proxy-smb-v1beta1 + - name: registration-dir + hostPath: + path: {{ .Values.windows.kubelet }}\plugins_registry\ + type: Directory + - name: kubelet-dir + hostPath: + path: {{ .Values.windows.kubelet }}\ + type: Directory + - name: plugin-dir + hostPath: + path: {{ .Values.windows.kubelet }}\plugins\{{ .Values.driver.name }}\ + type: DirectoryOrCreate + - name: azure-config + hostPath: + path: C:\k + type: Directory +{{- end -}} diff --git a/charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-node.yaml b/charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-node.yaml new file mode 100644 index 0000000000..60a746eb5d --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/templates/csi-azurefile-node.yaml @@ -0,0 +1,217 @@ +{{- if .Values.linux.enabled}} +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: {{ .Values.linux.dsName }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Values.linux.dsName }} + {{- include "azurefile.labels" . | nindent 4 }} +{{- with .Values.linux.labels }} +{{ . | toYaml | indent 4 }} +{{- end }} +{{- with .Values.linux.annotations }} + annotations: +{{ . | toYaml | indent 4 }} +{{- end }} +spec: + updateStrategy: + rollingUpdate: + maxUnavailable: {{ .Values.node.maxUnavailable }} + type: RollingUpdate + selector: + matchLabels: + app: {{ .Values.linux.dsName }} + {{- include "azurefile.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + app: {{ .Values.linux.dsName }} + {{- include "azurefile.labels" . | nindent 8 }} +{{- with .Values.linux.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.linux.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + spec: + hostNetwork: true + dnsPolicy: {{ .Values.linux.dnsPolicy }} + serviceAccountName: {{ .Values.serviceAccount.node }} + nodeSelector: + kubernetes.io/os: linux +{{- with .Values.linux.nodeSelector }} +{{ toYaml . | indent 8 }} +{{- end }} + affinity: +{{- with .Values.linux.affinity }} +{{ toYaml . | indent 8 }} +{{- end }} + nodeAffinity: +{{ toYaml .Values.linux.nodeAffinity | indent 10 }} + priorityClassName: system-node-critical +{{- with .Values.linux.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} +{{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + containers: + - name: liveness-probe + volumeMounts: + - mountPath: /csi + name: socket-dir +{{- if hasPrefix "/" .Values.image.livenessProbe.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- else }} + image: "{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- end }} + args: + - --csi-address=/csi/csi.sock + - --probe-timeout=3s + - --health-port={{ .Values.node.livenessProbe.healthPort }} + - --v=2 + imagePullPolicy: {{ .Values.image.livenessProbe.pullPolicy }} + resources: {{- toYaml .Values.linux.resources.livenessProbe | nindent 12 }} + - name: node-driver-registrar +{{- if hasPrefix "/" .Values.image.nodeDriverRegistrar.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.nodeDriverRegistrar.repository }}:{{ .Values.image.nodeDriverRegistrar.tag }}" +{{- else }} + image: "{{ .Values.image.nodeDriverRegistrar.repository }}:{{ .Values.image.nodeDriverRegistrar.tag }}" +{{- end }} + args: + - --csi-address=$(ADDRESS) + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --v=2 + livenessProbe: + exec: + command: + - /csi-node-driver-registrar + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --mode=kubelet-registration-probe + initialDelaySeconds: 30 + timeoutSeconds: 15 + env: + - name: ADDRESS + value: /csi/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: {{ .Values.linux.kubelet }}/plugins/{{ .Values.driver.name }}/csi.sock + imagePullPolicy: {{ .Values.image.nodeDriverRegistrar.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: registration-dir + mountPath: /registration + resources: {{- toYaml .Values.linux.resources.nodeDriverRegistrar | nindent 12 }} + - name: azurefile +{{- if hasPrefix "/" .Values.image.azurefile.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" +{{- else }} + image: "{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" +{{- end }} + args: + - "--v={{ .Values.node.logLevel }}" + - "--endpoint=$(CSI_ENDPOINT)" + - "--nodeid=$(KUBE_NODE_NAME)" + - "--metrics-address=0.0.0.0:{{ .Values.node.metricsPort }}" + - "--kubeconfig={{ .Values.linux.kubeconfig }}" + - "--drivername={{ .Values.driver.name }}" + - "--cloud-config-secret-name={{ .Values.node.cloudConfigSecretName }}" + - "--cloud-config-secret-namespace={{ .Values.node.cloudConfigSecretNamespace }}" + - "--custom-user-agent={{ .Values.driver.customUserAgent }}" + - "--user-agent-suffix={{ .Values.driver.userAgentSuffix }}" + - "--allow-empty-cloud-config={{ .Values.node.allowEmptyCloudConfig }}" + - "--enable-get-volume-stats={{ .Values.feature.enableGetVolumeStats }}" + - "--mount-permissions={{ .Values.linux.mountPermissions }}" + - "--allow-inline-volume-key-access-with-identity={{ .Values.node.allowInlineVolumeKeyAccessWithIdentity }}" + ports: + - containerPort: {{ .Values.node.livenessProbe.healthPort }} + name: healthz + protocol: TCP + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + timeoutSeconds: 10 + periodSeconds: 30 + env: + - name: AZURE_CREDENTIAL_FILE + valueFrom: + configMapKeyRef: + name: azure-cred-file + key: path + optional: true + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + {{- if ne .Values.driver.httpsProxy "" }} + - name: HTTPS_PROXY + value: {{ .Values.driver.httpsProxy }} + {{- end }} + {{- if ne .Values.driver.httpProxy "" }} + - name: HTTP_PROXY + value: {{ .Values.driver.httpProxy }} + {{- end }} + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: AZURE_GO_SDK_LOG_LEVEL + value: {{ .Values.driver.azureGoSDKLogLevel }} + imagePullPolicy: {{ .Values.image.azurefile.pullPolicy }} + securityContext: + privileged: true + volumeMounts: + - mountPath: /csi + name: socket-dir + - mountPath: {{ .Values.linux.kubelet }}/ + mountPropagation: Bidirectional + name: mountpoint-dir + - mountPath: /etc/kubernetes/ + name: azure-cred + - mountPath: /dev + name: device-dir + {{- if eq .Values.linux.distro "fedora" }} + - name: ssl + mountPath: /etc/ssl/certs + readOnly: true + - name: ssl-pki + mountPath: /etc/pki/ca-trust/extracted + readOnly: true + {{- end }} + resources: {{- toYaml .Values.linux.resources.azurefile | nindent 12 }} + volumes: + - hostPath: + path: {{ .Values.linux.kubelet }}/plugins/{{ .Values.driver.name }} + type: DirectoryOrCreate + name: socket-dir + - hostPath: + path: {{ .Values.linux.kubelet }}/ + type: DirectoryOrCreate + name: mountpoint-dir + - hostPath: + path: {{ .Values.linux.kubelet }}/plugins_registry/ + type: DirectoryOrCreate + name: registration-dir + - hostPath: + path: /etc/kubernetes/ + type: DirectoryOrCreate + name: azure-cred + - hostPath: + path: /dev + type: Directory + name: device-dir + {{- if eq .Values.linux.distro "fedora" }} + - name: ssl + hostPath: + path: /etc/ssl/certs + - name: ssl-pki + hostPath: + path: /etc/pki/ca-trust/extracted + {{- end }} +{{- end -}} diff --git a/charts/v1.26.0/azurefile-csi-driver/templates/csi-snapshot-controller.yaml b/charts/v1.26.0/azurefile-csi-driver/templates/csi-snapshot-controller.yaml new file mode 100644 index 0000000000..b1f7eff92c --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/templates/csi-snapshot-controller.yaml @@ -0,0 +1,65 @@ +{{- if .Values.snapshot.enabled -}} +kind: Deployment +apiVersion: apps/v1 +metadata: + name: {{ .Values.snapshot.snapshotController.name}} + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Values.snapshot.snapshotController.name}} + {{- include "azurefile.labels" . | nindent 4 }} +{{- with .Values.snapshot.snapshotController.labels }} +{{ . | toYaml | indent 4 }} +{{- end }} +{{- with .Values.snapshot.snapshotController.annotations }} + annotations: +{{ . | toYaml | indent 4 }} +{{- end }} +spec: + replicas: {{ .Values.snapshot.snapshotController.replicas }} + selector: + matchLabels: + app: {{ .Values.snapshot.snapshotController.name}} + {{- include "azurefile.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + app: {{ .Values.snapshot.snapshotController.name}} + {{- include "azurefile.labels" . | nindent 8 }} +{{- with .Values.snapshot.snapshotController.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.snapshot.snapshotController.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + spec: + serviceAccountName: {{ .Values.serviceAccount.snapshotController }} + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical +{{- with .Values.controller.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.controller.affinity }} + affinity: +{{ toYaml . | indent 8 }} +{{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + containers: + - name: {{ .Values.snapshot.snapshotController.name}} +{{- if hasPrefix "/" .Values.snapshot.image.csiSnapshotController.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.snapshot.image.csiSnapshotController.repository }}:{{ .Values.snapshot.image.csiSnapshotController.tag }}" +{{- else }} + image: "{{ .Values.snapshot.image.csiSnapshotController.repository }}:{{ .Values.snapshot.image.csiSnapshotController.tag }}" +{{- end }} + args: + - "--v=2" + - "--leader-election=true" + - "--leader-election-namespace={{ .Release.Namespace }}" + resources: {{- toYaml .Values.snapshot.snapshotController.resources | nindent 12 }} + imagePullPolicy: {{ .Values.snapshot.image.csiSnapshotController.pullPolicy }} +{{- end -}} diff --git a/charts/v1.26.0/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml b/charts/v1.26.0/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml new file mode 100644 index 0000000000..09923c06a5 --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml @@ -0,0 +1,207 @@ +{{- if .Values.rbac.create -}} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-external-provisioner-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +rules: + - 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: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["get", "list"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-csi-provisioner-binding + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.controller }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Values.rbac.name }}-external-provisioner-role + apiGroup: rbac.authorization.k8s.io + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-external-attacher-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +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", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-csi-attacher-binding + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.controller }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Values.rbac.name }}-external-attacher-role + apiGroup: rbac.authorization.k8s.io + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-external-snapshotter-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-csi-snapshotter-binding + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.controller }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Values.rbac.name }}-external-snapshotter-role + apiGroup: rbac.authorization.k8s.io + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-external-resizer-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-csi-resizer-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.controller }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Values.rbac.name }}-external-resizer-role + apiGroup: rbac.authorization.k8s.io + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-{{ .Values.rbac.name }}-controller-secret-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "create"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-{{ .Values.rbac.name }}-controller-secret-binding + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.controller }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-{{ .Values.rbac.name }}-controller-secret-role + apiGroup: rbac.authorization.k8s.io +{{ end }} diff --git a/charts/v1.26.0/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml b/charts/v1.26.0/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml new file mode 100644 index 0000000000..4e1fbcde94 --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml @@ -0,0 +1,29 @@ +{{- if .Values.rbac.create -}} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-{{ .Values.rbac.name }}-node-secret-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-{{ .Values.rbac.name }}-node-secret-binding + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.node }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-{{ .Values.rbac.name }}-node-secret-role + apiGroup: rbac.authorization.k8s.io +{{ end }} diff --git a/charts/v1.26.0/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml b/charts/v1.26.0/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml new file mode 100644 index 0000000000..0cff1ff01f --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml @@ -0,0 +1,80 @@ +{{- if and .Values.snapshot.enabled .Values.rbac.create -}} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch"] + - 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: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update", "patch"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-binding + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.snapshotController }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-snapshot-controller-role + apiGroup: rbac.authorization.k8s.io + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-leaderelection-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +rules: + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-leaderelection-binding + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.snapshotController }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-snapshot-controller-leaderelection-role + apiGroup: rbac.authorization.k8s.io +{{ end }} diff --git a/charts/v1.26.0/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml b/charts/v1.26.0/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml new file mode 100644 index 0000000000..66e0726acb --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml @@ -0,0 +1,9 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.controller }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "azurefile.labels" . | nindent 4 }} +{{- end -}} diff --git a/charts/v1.26.0/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml b/charts/v1.26.0/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml new file mode 100644 index 0000000000..697b8db390 --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml @@ -0,0 +1,9 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.node }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "azurefile.labels" . | nindent 4 }} +{{- end -}} diff --git a/charts/v1.26.0/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml b/charts/v1.26.0/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml new file mode 100644 index 0000000000..e77ef8f991 --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml @@ -0,0 +1,9 @@ +{{- if and .Values.snapshot.enabled .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.snapshotController }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "azurefile.labels" . | nindent 4 }} +{{- end -}} diff --git a/charts/v1.26.0/azurefile-csi-driver/values.yaml b/charts/v1.26.0/azurefile-csi-driver/values.yaml new file mode 100644 index 0000000000..043a5ad872 --- /dev/null +++ b/charts/v1.26.0/azurefile-csi-driver/values.yaml @@ -0,0 +1,254 @@ +image: + baseRepo: mcr.microsoft.com + azurefile: + repository: /oss/kubernetes-csi/azurefile-csi + tag: v1.26.0 + pullPolicy: IfNotPresent + csiProvisioner: + repository: /oss/kubernetes-csi/csi-provisioner + tag: v3.3.0 + pullPolicy: IfNotPresent + csiAttacher: + repository: /oss/kubernetes-csi/csi-attacher + tag: v4.0.0 + pullPolicy: IfNotPresent + csiResizer: + repository: /oss/kubernetes-csi/csi-resizer + tag: v1.6.0 + pullPolicy: IfNotPresent + livenessProbe: + repository: /oss/kubernetes-csi/livenessprobe + tag: v2.8.0 + pullPolicy: IfNotPresent + nodeDriverRegistrar: + repository: /oss/kubernetes-csi/csi-node-driver-registrar + tag: v2.6.2 + pullPolicy: IfNotPresent + +## Reference to one or more secrets to be used when pulling images +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] +# - name: myRegistryKeySecretName + +# -- Custom labels to add into metadata +customLabels: {} + # k8s-app: azurefile-csi-driver + +serviceAccount: + create: true # When true, service accounts will be created for you. Set to false if you want to use your own. + controller: csi-azurefile-controller-sa # Name of Service Account to be created or used + node: csi-azurefile-node-sa # Name of Service Account to be created or used + snapshotController: csi-snapshot-controller-sa # Name of Service Account to be created or used + +rbac: + create: true + name: azurefile + +controller: + name: csi-azurefile-controller + cloudConfigSecretName: azure-cloud-provider + cloudConfigSecretNamespace: kube-system + allowEmptyCloudConfig: true + replicas: 2 + hostNetwork: true # this setting could be disabled if controller does not depend on MSI setting + metricsPort: 29614 + livenessProbe: + healthPort: 29612 + runOnMaster: false + runOnControlPlane: false + attachRequired: false + logLevel: 5 + labels: {} + annotations: {} + podLabels: {} + podAnnotations: {} + resources: + csiProvisioner: + limits: + cpu: 1 + memory: 500Mi + requests: + cpu: 10m + memory: 20Mi + csiAttacher: + limits: + cpu: 1 + memory: 500Mi + requests: + cpu: 10m + memory: 20Mi + csiResizer: + limits: + cpu: 1 + memory: 500Mi + requests: + cpu: 10m + memory: 20Mi + csiSnapshotter: + limits: + cpu: 1 + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + livenessProbe: + limits: + cpu: 1 + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + azurefile: + limits: + cpu: 1 + memory: 200Mi + requests: + cpu: 10m + memory: 20Mi + kubeconfig: "" + affinity: {} + nodeSelector: {} + tolerations: + - key: "node-role.kubernetes.io/master" + operator: "Exists" + effect: "NoSchedule" + - key: "node-role.kubernetes.io/controlplane" + operator: "Exists" + effect: "NoSchedule" + - key: "node-role.kubernetes.io/control-plane" + operator: "Exists" + effect: "NoSchedule" + +node: + cloudConfigSecretName: azure-cloud-provider + cloudConfigSecretNamespace: kube-system + allowEmptyCloudConfig: true + allowInlineVolumeKeyAccessWithIdentity: false + metricsPort: 29615 + livenessProbe: + healthPort: 29613 + logLevel: 5 + +snapshot: + enabled: false + image: + csiSnapshotter: + repository: /oss/kubernetes-csi/csi-snapshotter + tag: v5.0.1 + pullPolicy: IfNotPresent + csiSnapshotController: + repository: /oss/kubernetes-csi/snapshot-controller + tag: v5.0.1 + pullPolicy: IfNotPresent + snapshotController: + name: csi-snapshot-controller + replicas: 2 + labels: {} + annotations: {} + podLabels: {} + podAnnotations: {} + resources: + limits: + cpu: 1 + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + +feature: + enableGetVolumeStats: true + +driver: + name: file.csi.azure.com + customUserAgent: "" + userAgentSuffix: "OSS-helm" + azureGoSDKLogLevel: "" # available values: ""(no logs), DEBUG, INFO, WARNING, ERROR + httpsProxy: "" + httpProxy: "" + +linux: + enabled: true + dsName: csi-azurefile-node # daemonset name + dnsPolicy: Default # available values: Default, ClusterFirst, ClusterFirstWithHostNet, None + kubelet: /var/lib/kubelet + kubeconfig: "" + distro: debian # available values: debian, fedora + mountPermissions: 0777 + labels: {} + annotations: {} + podLabels: {} + podAnnotations: {} + resources: + livenessProbe: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + nodeDriverRegistrar: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + azurefile: + limits: + memory: 400Mi + requests: + cpu: 10m + memory: 20Mi + tolerations: + - operator: "Exists" + nodeSelector: {} + affinity: {} + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: type + operator: NotIn + values: + - virtual-kubelet + +windows: + enabled: true + dsName: csi-azurefile-node-win # daemonset name + kubelet: 'C:\var\lib\kubelet' + kubeconfig: "" + labels: {} + annotations: {} + podLabels: {} + podAnnotations: {} + resources: + livenessProbe: + limits: + memory: 150Mi + requests: + cpu: 10m + memory: 40Mi + nodeDriverRegistrar: + limits: + memory: 150Mi + requests: + cpu: 30m + memory: 40Mi + azurefile: + limits: + memory: 200Mi + requests: + cpu: 10m + memory: 40Mi + tolerations: + - key: "node.kubernetes.io/os" + operator: "Exists" + effect: "NoSchedule" + nodeSelector: {} + affinity: {} + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: type + operator: NotIn + values: + - virtual-kubelet diff --git a/deploy/csi-azurefile-controller.yaml b/deploy/csi-azurefile-controller.yaml index 623890f3ee..4e711568da 100644 --- a/deploy/csi-azurefile-controller.yaml +++ b/deploy/csi-azurefile-controller.yaml @@ -133,7 +133,7 @@ spec: cpu: 10m memory: 20Mi - name: azurefile - image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest + image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.0 imagePullPolicy: IfNotPresent args: - "--v=5" diff --git a/deploy/csi-azurefile-driver.yaml b/deploy/csi-azurefile-driver.yaml index 55d31ed2d1..3b5fb795fc 100644 --- a/deploy/csi-azurefile-driver.yaml +++ b/deploy/csi-azurefile-driver.yaml @@ -4,7 +4,7 @@ kind: CSIDriver metadata: name: file.csi.azure.com annotations: - csiDriver: latest + csiDriver: v1.26.0 snapshot: v5.0.1 spec: attachRequired: false diff --git a/deploy/csi-azurefile-node-windows.yaml b/deploy/csi-azurefile-node-windows.yaml index 9340864653..82eaf817f4 100644 --- a/deploy/csi-azurefile-node-windows.yaml +++ b/deploy/csi-azurefile-node-windows.yaml @@ -91,7 +91,7 @@ spec: cpu: 30m memory: 40Mi - name: azurefile - image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest + image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.0 imagePullPolicy: IfNotPresent args: - --v=5 diff --git a/deploy/csi-azurefile-node.yaml b/deploy/csi-azurefile-node.yaml index f36a6a9545..66f858c7bd 100644 --- a/deploy/csi-azurefile-node.yaml +++ b/deploy/csi-azurefile-node.yaml @@ -82,7 +82,7 @@ spec: cpu: 10m memory: 20Mi - name: azurefile - image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest + image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.0 imagePullPolicy: IfNotPresent args: - "--v=5" diff --git a/deploy/v1.26.0/crd-csi-snapshot.yaml b/deploy/v1.26.0/crd-csi-snapshot.yaml new file mode 100644 index 0000000000..18d97e6b7c --- /dev/null +++ b/deploy/v1.26.0/crd-csi-snapshot.yaml @@ -0,0 +1,659 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + creationTimestamp: null + name: volumesnapshots.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshot + listKind: VolumeSnapshotList + plural: volumesnapshots + shortNames: + - vs + singular: volumesnapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' + properties: + source: + description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. + type: string + type: object + oneOf: + - required: ["persistentVolumeClaimName"] + - required: ["volumeSnapshotContentName"] + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurrs during the snapshot creation. Upon success, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + type: string + description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshot is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshot" + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' + properties: + source: + description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurrs during the snapshot creation. Upon success, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + type: string + description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + creationTimestamp: null + name: volumesnapshotclasses.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotClass + listKind: VolumeSnapshotClassList + plural: volumesnapshotclasses + shortNames: + - vsclass + - vsclasses + singular: volumesnapshotclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotClass is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotClass" + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + creationTimestamp: null + name: volumesnapshotcontents.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotContent + listKind: VolumeSnapshotContentList + plural: volumesnapshotcontents + shortNames: + - vsc + - vscs + singular: volumesnapshotcontent + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. + type: string + type: object + oneOf: + - required: ["snapshotHandle"] + - required: ["volumeHandle"] + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotContent is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotContent" + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. + type: string + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] \ No newline at end of file diff --git a/deploy/v1.26.0/csi-azurefile-controller.yaml b/deploy/v1.26.0/csi-azurefile-controller.yaml new file mode 100644 index 0000000000..4e711568da --- /dev/null +++ b/deploy/v1.26.0/csi-azurefile-controller.yaml @@ -0,0 +1,184 @@ +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: csi-azurefile-controller + namespace: kube-system +spec: + replicas: 2 + selector: + matchLabels: + app: csi-azurefile-controller + template: + metadata: + labels: + app: csi-azurefile-controller + spec: + hostNetwork: true # only required for MSI enabled cluster + serviceAccountName: csi-azurefile-controller-sa + nodeSelector: + kubernetes.io/os: linux # add "kubernetes.io/role: master" to run controller on master node + priorityClassName: system-cluster-critical + tolerations: + - key: "node-role.kubernetes.io/master" + operator: "Exists" + effect: "NoSchedule" + - key: "node-role.kubernetes.io/controlplane" + operator: "Exists" + effect: "NoSchedule" + - key: "node-role.kubernetes.io/control-plane" + operator: "Exists" + effect: "NoSchedule" + containers: + - name: csi-provisioner + image: mcr.microsoft.com/oss/kubernetes-csi/csi-provisioner:v3.3.0 + args: + - "-v=2" + - "--csi-address=$(ADDRESS)" + - "--leader-election" + - "--leader-election-namespace=kube-system" + - "--timeout=300s" + - "--extra-create-metadata=true" + - "--kube-api-qps=50" + - "--kube-api-burst=100" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - mountPath: /csi + name: socket-dir + resources: + limits: + memory: 500Mi + requests: + cpu: 10m + memory: 20Mi + - name: csi-attacher + image: mcr.microsoft.com/oss/kubernetes-csi/csi-attacher:v4.0.0 + args: + - "-v=2" + - "-csi-address=$(ADDRESS)" + - "-timeout=120s" + - "--leader-election" + - "--leader-election-namespace=kube-system" + - "--kube-api-qps=50" + - "--kube-api-burst=100" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - mountPath: /csi + name: socket-dir + resources: + limits: + memory: 500Mi + requests: + cpu: 10m + memory: 20Mi + - name: csi-snapshotter + image: mcr.microsoft.com/oss/kubernetes-csi/csi-snapshotter:v5.0.1 + args: + - "-v=2" + - "-csi-address=$(ADDRESS)" + - "--leader-election" + - "--leader-election-namespace=kube-system" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /csi + resources: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + - name: csi-resizer + image: mcr.microsoft.com/oss/kubernetes-csi/csi-resizer:v1.6.0 + args: + - "-csi-address=$(ADDRESS)" + - "-v=2" + - "--leader-election" + - "--leader-election-namespace=kube-system" + - '-handle-volume-inuse-error=false' + - '-feature-gates=RecoverVolumeExpansionFailure=true' + - '-timeout=120s' + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /csi + resources: + limits: + memory: 500Mi + requests: + cpu: 10m + memory: 20Mi + - name: liveness-probe + image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.8.0 + args: + - --csi-address=/csi/csi.sock + - --probe-timeout=3s + - --health-port=29612 + - --v=2 + volumeMounts: + - name: socket-dir + mountPath: /csi + resources: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + - name: azurefile + image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.0 + imagePullPolicy: IfNotPresent + args: + - "--v=5" + - "--endpoint=$(CSI_ENDPOINT)" + - "--metrics-address=0.0.0.0:29614" + - "--user-agent-suffix=OSS-kubectl" + ports: + - containerPort: 29612 + name: healthz + protocol: TCP + - containerPort: 29614 + name: metrics + protocol: TCP + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + timeoutSeconds: 10 + periodSeconds: 30 + env: + - name: AZURE_CREDENTIAL_FILE + valueFrom: + configMapKeyRef: + name: azure-cred-file + key: path + optional: true + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + volumeMounts: + - mountPath: /csi + name: socket-dir + - mountPath: /etc/kubernetes/ + name: azure-cred + resources: + limits: + memory: 200Mi + requests: + cpu: 10m + memory: 20Mi + volumes: + - name: socket-dir + emptyDir: {} + - name: azure-cred + hostPath: + path: /etc/kubernetes/ + type: DirectoryOrCreate diff --git a/deploy/v1.26.0/csi-azurefile-driver.yaml b/deploy/v1.26.0/csi-azurefile-driver.yaml new file mode 100644 index 0000000000..3b5fb795fc --- /dev/null +++ b/deploy/v1.26.0/csi-azurefile-driver.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: file.csi.azure.com + annotations: + csiDriver: v1.26.0 + snapshot: v5.0.1 +spec: + attachRequired: false + podInfoOnMount: true + volumeLifecycleModes: + - Persistent + - Ephemeral + fsGroupPolicy: ReadWriteOnceWithFSType diff --git a/deploy/v1.26.0/csi-azurefile-node-windows.yaml b/deploy/v1.26.0/csi-azurefile-node-windows.yaml new file mode 100644 index 0000000000..82eaf817f4 --- /dev/null +++ b/deploy/v1.26.0/csi-azurefile-node-windows.yaml @@ -0,0 +1,181 @@ +--- +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: csi-azurefile-node-win + namespace: kube-system +spec: + updateStrategy: + rollingUpdate: + maxUnavailable: 1 + type: RollingUpdate + selector: + matchLabels: + app: csi-azurefile-node-win + template: + metadata: + labels: + app: csi-azurefile-node-win + spec: + serviceAccountName: csi-azurefile-node-sa + tolerations: + - key: "node.kubernetes.io/os" + operator: "Exists" + effect: "NoSchedule" + nodeSelector: + kubernetes.io/os: windows + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: type + operator: NotIn + values: + - virtual-kubelet + priorityClassName: system-node-critical + containers: + - name: liveness-probe + volumeMounts: + - mountPath: C:\csi + name: plugin-dir + image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.8.0 + args: + - --csi-address=$(CSI_ENDPOINT) + - --probe-timeout=3s + - --health-port=29613 + - --v=2 + env: + - name: CSI_ENDPOINT + value: unix://C:\\csi\\csi.sock + resources: + limits: + memory: 150Mi + requests: + cpu: 10m + memory: 40Mi + - name: node-driver-registrar + image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.6.2 + args: + - --v=2 + - --csi-address=$(CSI_ENDPOINT) + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + livenessProbe: + exec: + command: + - /csi-node-driver-registrar.exe + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --mode=kubelet-registration-probe + initialDelaySeconds: 60 + timeoutSeconds: 30 + env: + - name: CSI_ENDPOINT + value: unix://C:\\csi\\csi.sock + - name: DRIVER_REG_SOCK_PATH + value: C:\\var\\lib\\kubelet\\plugins\\file.csi.azure.com\\csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + volumeMounts: + - name: kubelet-dir + mountPath: "C:\\var\\lib\\kubelet" + - name: plugin-dir + mountPath: C:\csi + - name: registration-dir + mountPath: C:\registration + resources: + limits: + memory: 150Mi + requests: + cpu: 30m + memory: 40Mi + - name: azurefile + image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.0 + imagePullPolicy: IfNotPresent + args: + - --v=5 + - --endpoint=$(CSI_ENDPOINT) + - --nodeid=$(KUBE_NODE_NAME) + - --kubeconfig=C:\\k\\config + - --metrics-address=0.0.0.0:29615 + ports: + - containerPort: 29613 + name: healthz + protocol: TCP + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + timeoutSeconds: 10 + periodSeconds: 30 + env: + - name: AZURE_CREDENTIAL_FILE + valueFrom: + configMapKeyRef: + name: azure-cred-file + key: path-windows + optional: true + - name: CSI_ENDPOINT + value: unix://C:\\csi\\csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + volumeMounts: + - name: kubelet-dir + mountPath: "C:\\var\\lib\\kubelet" + - name: plugin-dir + mountPath: C:\csi + - name: azure-config + mountPath: C:\k + - name: csi-proxy-fs-pipe-v1 + mountPath: \\.\pipe\csi-proxy-filesystem-v1 + - name: csi-proxy-smb-pipe-v1 + mountPath: \\.\pipe\csi-proxy-smb-v1 + # these paths are still included for compatibility, they're used + # only if the node has still the beta version of the CSI proxy + - name: csi-proxy-fs-pipe-v1beta1 + mountPath: \\.\pipe\csi-proxy-filesystem-v1beta1 + - name: csi-proxy-smb-pipe-v1beta1 + mountPath: \\.\pipe\csi-proxy-smb-v1beta1 + resources: + limits: + memory: 200Mi + requests: + cpu: 10m + memory: 40Mi + volumes: + - name: csi-proxy-fs-pipe-v1 + hostPath: + path: \\.\pipe\csi-proxy-filesystem-v1 + - name: csi-proxy-smb-pipe-v1 + hostPath: + path: \\.\pipe\csi-proxy-smb-v1 + # these paths are still included for compatibility, they're used + # only if the node has still the beta version of the CSI proxy + - name: csi-proxy-fs-pipe-v1beta1 + hostPath: + path: \\.\pipe\csi-proxy-filesystem-v1beta1 + - name: csi-proxy-smb-pipe-v1beta1 + hostPath: + path: \\.\pipe\csi-proxy-smb-v1beta1 + - name: registration-dir + hostPath: + path: C:\var\lib\kubelet\plugins_registry\ + type: Directory + - name: kubelet-dir + hostPath: + path: C:\var\lib\kubelet\ + type: Directory + - name: plugin-dir + hostPath: + path: C:\var\lib\kubelet\plugins\file.csi.azure.com\ + type: DirectoryOrCreate + - name: azure-config + hostPath: + path: C:\k + type: DirectoryOrCreate diff --git a/deploy/v1.26.0/csi-azurefile-node.yaml b/deploy/v1.26.0/csi-azurefile-node.yaml new file mode 100644 index 0000000000..66f858c7bd --- /dev/null +++ b/deploy/v1.26.0/csi-azurefile-node.yaml @@ -0,0 +1,157 @@ +--- +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: csi-azurefile-node + namespace: kube-system +spec: + updateStrategy: + rollingUpdate: + maxUnavailable: 1 + type: RollingUpdate + selector: + matchLabels: + app: csi-azurefile-node + template: + metadata: + labels: + app: csi-azurefile-node + spec: + hostNetwork: true + dnsPolicy: Default + serviceAccountName: csi-azurefile-node-sa + nodeSelector: + kubernetes.io/os: linux + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: type + operator: NotIn + values: + - virtual-kubelet + priorityClassName: system-node-critical + tolerations: + - operator: "Exists" + containers: + - name: liveness-probe + volumeMounts: + - mountPath: /csi + name: socket-dir + image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.8.0 + args: + - --csi-address=/csi/csi.sock + - --probe-timeout=3s + - --health-port=29613 + - --v=2 + resources: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + - name: node-driver-registrar + image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.6.2 + args: + - --csi-address=$(ADDRESS) + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --v=2 + livenessProbe: + exec: + command: + - /csi-node-driver-registrar + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --mode=kubelet-registration-probe + initialDelaySeconds: 30 + timeoutSeconds: 15 + env: + - name: ADDRESS + value: /csi/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: /var/lib/kubelet/plugins/file.csi.azure.com/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: registration-dir + mountPath: /registration + resources: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + - name: azurefile + image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.0 + imagePullPolicy: IfNotPresent + args: + - "--v=5" + - "--endpoint=$(CSI_ENDPOINT)" + - "--nodeid=$(KUBE_NODE_NAME)" + - "--metrics-address=0.0.0.0:29615" + ports: + - containerPort: 29613 + name: healthz + protocol: TCP + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + timeoutSeconds: 10 + periodSeconds: 30 + env: + - name: AZURE_CREDENTIAL_FILE + valueFrom: + configMapKeyRef: + name: azure-cred-file + key: path + optional: true + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + securityContext: + privileged: true + volumeMounts: + - mountPath: /csi + name: socket-dir + - mountPath: /var/lib/kubelet/ + mountPropagation: Bidirectional + name: mountpoint-dir + - mountPath: /etc/kubernetes/ + name: azure-cred + - mountPath: /dev + name: device-dir + resources: + limits: + memory: 400Mi + requests: + cpu: 10m + memory: 20Mi + volumes: + - hostPath: + path: /var/lib/kubelet/plugins/file.csi.azure.com + type: DirectoryOrCreate + name: socket-dir + - hostPath: + path: /var/lib/kubelet/ + type: DirectoryOrCreate + name: mountpoint-dir + - hostPath: + path: /var/lib/kubelet/plugins_registry/ + type: DirectoryOrCreate + name: registration-dir + - hostPath: + path: /etc/kubernetes/ + type: DirectoryOrCreate + name: azure-cred + - hostPath: + path: /dev + type: Directory + name: device-dir +--- diff --git a/deploy/v1.26.0/csi-snapshot-controller.yaml b/deploy/v1.26.0/csi-snapshot-controller.yaml new file mode 100644 index 0000000000..79c7483bb5 --- /dev/null +++ b/deploy/v1.26.0/csi-snapshot-controller.yaml @@ -0,0 +1,46 @@ +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: csi-snapshot-controller + namespace: kube-system +spec: + replicas: 2 + selector: + matchLabels: + app: csi-snapshot-controller + template: + metadata: + labels: + app: csi-snapshot-controller + spec: + serviceAccountName: csi-snapshot-controller-sa + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + tolerations: + - key: "node-role.kubernetes.io/master" + operator: "Equal" + value: "true" + effect: "NoSchedule" + - key: "node-role.kubernetes.io/controlplane" + operator: "Equal" + value: "true" + effect: "NoSchedule" + - key: "node-role.kubernetes.io/control-plane" + operator: "Equal" + value: "true" + effect: "NoSchedule" + containers: + - name: csi-snapshot-controller + image: mcr.microsoft.com/oss/kubernetes-csi/snapshot-controller:v5.0.1 + args: + - "--v=2" + - "--leader-election=true" + - "--leader-election-namespace=kube-system" + resources: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi diff --git a/deploy/v1.26.0/rbac-csi-azurefile-controller.yaml b/deploy/v1.26.0/rbac-csi-azurefile-controller.yaml new file mode 100644 index 0000000000..b9348c8cd5 --- /dev/null +++ b/deploy/v1.26.0/rbac-csi-azurefile-controller.yaml @@ -0,0 +1,194 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-azurefile-controller-sa + namespace: kube-system + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-external-provisioner-role +rules: + - 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: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["get", "list"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-csi-provisioner-binding +subjects: + - kind: ServiceAccount + name: csi-azurefile-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: azurefile-external-provisioner-role + apiGroup: rbac.authorization.k8s.io + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-external-attacher-role +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", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-csi-attacher-binding +subjects: + - kind: ServiceAccount + name: csi-azurefile-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: azurefile-external-attacher-role + apiGroup: rbac.authorization.k8s.io + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-external-snapshotter-role +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-csi-snapshotter-binding +subjects: + - kind: ServiceAccount + name: csi-azurefile-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: azurefile-external-snapshotter-role + apiGroup: rbac.authorization.k8s.io + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-external-resizer-role +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-csi-resizer-role +subjects: + - kind: ServiceAccount + name: csi-azurefile-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: azurefile-external-resizer-role + apiGroup: rbac.authorization.k8s.io + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-azurefile-controller-secret-role +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "create"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-azurefile-controller-secret-binding +subjects: + - kind: ServiceAccount + name: csi-azurefile-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: csi-azurefile-controller-secret-role + apiGroup: rbac.authorization.k8s.io diff --git a/deploy/v1.26.0/rbac-csi-azurefile-node.yaml b/deploy/v1.26.0/rbac-csi-azurefile-node.yaml new file mode 100644 index 0000000000..3752f36aa4 --- /dev/null +++ b/deploy/v1.26.0/rbac-csi-azurefile-node.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-azurefile-node-sa + namespace: kube-system + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-azurefile-node-secret-role +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-azurefile-node-secret-binding +subjects: + - kind: ServiceAccount + name: csi-azurefile-node-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: csi-azurefile-node-secret-role + apiGroup: rbac.authorization.k8s.io diff --git a/deploy/v1.26.0/rbac-csi-snapshot-controller.yaml b/deploy/v1.26.0/rbac-csi-snapshot-controller.yaml new file mode 100644 index 0000000000..03af765424 --- /dev/null +++ b/deploy/v1.26.0/rbac-csi-snapshot-controller.yaml @@ -0,0 +1,78 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-snapshot-controller-sa + namespace: kube-system + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-role +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch"] + - 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: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update", "patch"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-binding +subjects: + - kind: ServiceAccount + name: csi-snapshot-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: csi-snapshot-controller-role + apiGroup: rbac.authorization.k8s.io + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-leaderelection-role +rules: + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-leaderelection-binding +subjects: + - kind: ServiceAccount + name: csi-snapshot-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: csi-snapshot-controller-leaderelection-role + apiGroup: rbac.authorization.k8s.io diff --git a/docs/install-azurefile-csi-driver.md b/docs/install-azurefile-csi-driver.md index d4b85db03f..83c0c73f7d 100644 --- a/docs/install-azurefile-csi-driver.md +++ b/docs/install-azurefile-csi-driver.md @@ -4,6 +4,6 @@ > - please use helm install method for more customization, e.g. Azure Stack, RedHat OpenShift support. - [install CSI driver master version](./install-csi-driver-master.md)(only for testing purpose) + - [install v1.26.0 CSI driver](./install-csi-driver-v1.26.0.md) - [install v1.25.1 CSI driver](./install-csi-driver-v1.25.1.md) - [install v1.24.0 CSI driver](./install-csi-driver-v1.24.0.md) - - [install v1.23.0 CSI driver](./install-csi-driver-v1.23.0.md) diff --git a/docs/install-csi-driver-v1.26.0.md b/docs/install-csi-driver-v1.26.0.md new file mode 100644 index 0000000000..f60122eed0 --- /dev/null +++ b/docs/install-csi-driver-v1.26.0.md @@ -0,0 +1,45 @@ +## Install azurefile CSI driver v1.26.0 version on a Kubernetes cluster +If you have already installed Helm, you can also use it to install this driver. Please check [Installation with Helm](../charts/README.md). + +### Install by kubectl + - Option#1. remote install +```console +curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/v1.26.0/deploy/install-driver.sh | bash -s v1.26.0 -- +``` + + - Option#2. local install +```console +git clone https://github.com/kubernetes-sigs/azurefile-csi-driver.git +cd azurefile-csi-driver +git checkout v1.26.0 +./deploy/install-driver.sh v1.26.0 local +``` + + - check pods status: +```console +kubectl -n kube-system get pod -o wide --watch -l app=csi-azurefile-controller +kubectl -n kube-system get pod -o wide --watch -l app=csi-azurefile-node +``` + +example output: + +``` +NAME READY STATUS RESTARTS AGE IP NODE +csi-azurefile-controller-56bfddd689-dh5tk 6/6 Running 0 35s 10.240.0.19 k8s-agentpool-22533604-0 +csi-azurefile-node-cvgbs 3/3 Running 0 7m4s 10.240.0.35 k8s-agentpool-22533604-1 +csi-azurefile-node-dr4s4 3/3 Running 0 7m4s 10.240.0.4 k8s-agentpool-22533604-0 +``` + +### clean up CSI driver + - Option#1. remote uninstall +```console +curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/v1.26.0/deploy/uninstall-driver.sh | bash -s -- +``` + + - Option#2. local uninstall +```console +git clone https://github.com/kubernetes-sigs/azurefile-csi-driver.git +cd azurefile-csi-driver +git checkout v1.26.0 +./deploy/install-driver.sh v1.26.0 local +``` From a13c917d9b6f52153d365b9894476b1734457a80 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Fri, 10 Feb 2023 02:49:19 +0000 Subject: [PATCH 018/109] doc: use latest version for master branch --- charts/index.yaml | 76 +++++++++--------- charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 0 -> 11432 bytes .../latest/azurefile-csi-driver-v1.26.0.tgz | Bin 11417 -> 0 bytes charts/latest/azurefile-csi-driver/Chart.yaml | 4 +- .../latest/azurefile-csi-driver/values.yaml | 4 +- deploy/csi-azurefile-controller.yaml | 2 +- deploy/csi-azurefile-driver.yaml | 2 +- deploy/csi-azurefile-node-windows.yaml | 2 +- deploy/csi-azurefile-node.yaml | 2 +- 9 files changed, 46 insertions(+), 46 deletions(-) create mode 100644 charts/latest/azurefile-csi-driver-v0.0.0.tgz delete mode 100644 charts/latest/azurefile-csi-driver-v1.26.0.tgz diff --git a/charts/index.yaml b/charts/index.yaml index 7686add942..f79db5d256 100644 --- a/charts/index.yaml +++ b/charts/index.yaml @@ -3,16 +3,7 @@ entries: azurefile-csi-driver: - apiVersion: v1 appVersion: v1.26.0 - created: "2023-02-10T02:47:55.453528262Z" - description: Azure File Container Storage Interface (CSI) Storage Plugin - digest: 71f843ca5c1bf23cf484eaa404dfb27c6f9d614a7b4d672331dd8c9fe36ced06 - name: azurefile-csi-driver - urls: - - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/latest/azurefile-csi-driver-v1.26.0.tgz - version: v1.26.0 - - apiVersion: v1 - appVersion: v1.26.0 - created: "2023-02-10T02:47:55.50942039Z" + created: "2023-02-10T02:49:15.131414709Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 98d15a8ced671a7c3d9aec8ebe00b58abeecb5f65ab966c9c01c4f39121adc0c name: azurefile-csi-driver @@ -21,7 +12,7 @@ entries: version: v1.26.0 - apiVersion: v1 appVersion: v1.25.1 - created: "2023-02-10T02:47:55.508434805Z" + created: "2023-02-10T02:49:15.130456807Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 2bf374cc321c5bc8e76e06cd5df85ce7d7d14574397e7e7f7173077393f554c4 name: azurefile-csi-driver @@ -30,7 +21,7 @@ entries: version: v1.25.1 - apiVersion: v1 appVersion: v1.25.0 - created: "2023-02-10T02:47:55.507255598Z" + created: "2023-02-10T02:49:15.129444021Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: ba80dcd23dade4e62b39d3dc638c599e9d5e100009fa14d4164bfc8966fea3dd name: azurefile-csi-driver @@ -39,7 +30,7 @@ entries: version: v1.25.0 - apiVersion: v1 appVersion: v1.24.0 - created: "2023-02-10T02:47:55.502796536Z" + created: "2023-02-10T02:49:15.128438281Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 1905eb862745d4a7f57c5de96848cee194adf827086984b75bcaefce5c90142b name: azurefile-csi-driver @@ -48,7 +39,7 @@ entries: version: v1.24.0 - apiVersion: v1 appVersion: v1.23.0 - created: "2023-02-10T02:47:55.498925196Z" + created: "2023-02-10T02:49:15.126899719Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 5fcb33617d16e90df1e7041b0df02e5bd92595e86381db30d356b0b2e3500bc4 name: azurefile-csi-driver @@ -57,7 +48,7 @@ entries: version: v1.23.0 - apiVersion: v1 appVersion: v1.22.0 - created: "2023-02-10T02:47:55.496694137Z" + created: "2023-02-10T02:49:15.125674354Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 253d87a8b876dbdd55870a7fee88547393179d03f193661125f5a0b63411f922 name: azurefile-csi-driver @@ -66,7 +57,7 @@ entries: version: v1.22.0 - apiVersion: v1 appVersion: v1.21.0 - created: "2023-02-10T02:47:55.495570131Z" + created: "2023-02-10T02:49:15.124674922Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: d45bf3455ebadc9cc5afaf9da66aa1ea1d4b719cfdff5af661f93bb26c01a504 name: azurefile-csi-driver @@ -75,7 +66,7 @@ entries: version: v1.21.0 - apiVersion: v1 appVersion: v1.20.0 - created: "2023-02-10T02:47:55.494479748Z" + created: "2023-02-10T02:49:15.123744091Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 7cc43d57a79137aea5414fb51a9bbd77bb679b29ee49c06865c1a5b9ba60be99 name: azurefile-csi-driver @@ -84,7 +75,7 @@ entries: version: v1.20.0 - apiVersion: v1 appVersion: v1.19.0 - created: "2023-02-10T02:47:55.487060353Z" + created: "2023-02-10T02:49:15.122285936Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 18f6efbed424efd661fde43be2e5a48a5012a46a7938c33b36963cbd9875a5af name: azurefile-csi-driver @@ -93,7 +84,7 @@ entries: version: v1.19.0 - apiVersion: v1 appVersion: v1.18.0 - created: "2023-02-10T02:47:55.485989416Z" + created: "2023-02-10T02:49:15.120528972Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 696ca23d9ee517f71ef5e852955c8d0f1017c331c025426c6fcbe7a06d006c66 name: azurefile-csi-driver @@ -102,7 +93,7 @@ entries: version: v1.18.0 - apiVersion: v1 appVersion: v1.17.0 - created: "2023-02-10T02:47:55.484076077Z" + created: "2023-02-10T02:49:15.1196304Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 5632f61265a3b78dce3e2b15e07cc9b14a7f54a778878c02ca2d9fe69ca0344e name: azurefile-csi-driver @@ -111,7 +102,7 @@ entries: version: v1.17.0 - apiVersion: v1 appVersion: v1.16.0 - created: "2023-02-10T02:47:55.482981458Z" + created: "2023-02-10T02:49:15.118707997Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: a7a2d57e8eca7dc06c8b2cffb9bccb857753eb110b8e70760b3e04f4e6a87552 name: azurefile-csi-driver @@ -120,7 +111,7 @@ entries: version: v1.16.0 - apiVersion: v1 appVersion: v1.15.0 - created: "2023-02-10T02:47:55.479494726Z" + created: "2023-02-10T02:49:15.117817743Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: c1a31dadce233a90c19dce70f6cc92ba2e20bbaa1b1883baea72381d09303118 name: azurefile-csi-driver @@ -129,7 +120,7 @@ entries: version: v1.15.0 - apiVersion: v1 appVersion: v1.14.0 - created: "2023-02-10T02:47:55.478417345Z" + created: "2023-02-10T02:49:15.116852798Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 0c9ad4afa5ebfdb2851ad93eb16a0382d61448714b7556899360730a2fdf463a name: azurefile-csi-driver @@ -138,7 +129,7 @@ entries: version: v1.14.0 - apiVersion: v1 appVersion: v1.13.0 - created: "2023-02-10T02:47:55.47472126Z" + created: "2023-02-10T02:49:15.115929349Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 214042b029d858b50a0f8bba33a7aa2b41d1b67bce16f957ca183ae7438dac3f name: azurefile-csi-driver @@ -147,7 +138,7 @@ entries: version: v1.13.0 - apiVersion: v1 appVersion: v1.12.0 - created: "2023-02-10T02:47:55.470657536Z" + created: "2023-02-10T02:49:15.114589222Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: fbd63929671066a26df898d32282a6e79c39499a39c71761c546d069459d847d name: azurefile-csi-driver @@ -156,7 +147,7 @@ entries: version: v1.12.0 - apiVersion: v1 appVersion: v1.11.0 - created: "2023-02-10T02:47:55.466080724Z" + created: "2023-02-10T02:49:15.113369009Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 76bd438f8391d08235b09fbca859f25a9fcf8e018fd1e7e33444ca9ea946ce4b name: azurefile-csi-driver @@ -165,7 +156,7 @@ entries: version: v1.11.0 - apiVersion: v1 appVersion: v1.10.0 - created: "2023-02-10T02:47:55.464087272Z" + created: "2023-02-10T02:49:15.112179371Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 845a9de8b571b255d05ae9c643d9b90a57fe6507ff3fb735c88b41f99f6f28dc name: azurefile-csi-driver @@ -174,7 +165,7 @@ entries: version: v1.10.0 - apiVersion: v1 appVersion: v1.9.0 - created: "2023-02-10T02:47:55.520423456Z" + created: "2023-02-10T02:49:15.137574748Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 59a8057fbbd6d59919b84ef0c3396d5a0a46d1f29df604457db676f4af63c714 name: azurefile-csi-driver @@ -183,7 +174,7 @@ entries: version: v1.9.0 - apiVersion: v1 appVersion: v1.8.0 - created: "2023-02-10T02:47:55.518304685Z" + created: "2023-02-10T02:49:15.136616431Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 455b7c342194311046df526d10926d94f3bef24f753a07003fb1cad211c4cb52 name: azurefile-csi-driver @@ -192,7 +183,7 @@ entries: version: v1.8.0 - apiVersion: v1 appVersion: v1.7.0 - created: "2023-02-10T02:47:55.517159805Z" + created: "2023-02-10T02:49:15.135630744Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 057b3f6ef6001d3457fbffc27f90316c981a089696abd3d38bcc8de5537dfa6f name: azurefile-csi-driver @@ -201,7 +192,7 @@ entries: version: v1.7.0 - apiVersion: v1 appVersion: v1.6.0 - created: "2023-02-10T02:47:55.516288668Z" + created: "2023-02-10T02:49:15.1348858Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: cc2a0dda824cdda4e8141e26878bbb481c5a52e45785a5dbf72e54f2a376e522 name: azurefile-csi-driver @@ -210,7 +201,7 @@ entries: version: v1.6.0 - apiVersion: v1 appVersion: v1.5.0 - created: "2023-02-10T02:47:55.515428634Z" + created: "2023-02-10T02:49:15.134137781Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 2258177477415ddecd83dc46dfd88833223623224c7fe396590b617082bcd845 name: azurefile-csi-driver @@ -219,7 +210,7 @@ entries: version: v1.5.0 - apiVersion: v1 appVersion: v1.4.0 - created: "2023-02-10T02:47:55.514592609Z" + created: "2023-02-10T02:49:15.132561785Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 40e9bc4ee187789166fcb7c3c82b85b33ecd3a6096266fe74e411d6b48961ece name: azurefile-csi-driver @@ -228,7 +219,7 @@ entries: version: v1.4.0 - apiVersion: v1 appVersion: v1.3.0 - created: "2023-02-10T02:47:55.511384373Z" + created: "2023-02-10T02:49:15.131929231Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 12942f422b7cccbfe950bbdbd5c844f5ae4b7c292f32389cba312730a6fe9a62 name: azurefile-csi-driver @@ -237,7 +228,7 @@ entries: version: v1.3.0 - apiVersion: v1 appVersion: v1.2.0 - created: "2023-02-10T02:47:55.490473708Z" + created: "2023-02-10T02:49:15.12282244Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: b62f44b757416a9e1f5a91e19285f5f5056ec6068802dd9cd82373bef40c9ee9 name: azurefile-csi-driver @@ -246,7 +237,7 @@ entries: version: v1.2.0 - apiVersion: v1 appVersion: v1.1.0 - created: "2023-02-10T02:47:55.462914131Z" + created: "2023-02-10T02:49:15.111266014Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 675d96b309a1c5c491053ebbb854c046737420929c4f0692839afdaaf0db3933 name: azurefile-csi-driver @@ -255,11 +246,20 @@ entries: version: v1.1.0 - apiVersion: v1 appVersion: v1.0.0 - created: "2023-02-10T02:47:55.457277198Z" + created: "2023-02-10T02:49:15.110779468Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 6fd5e54e949ef1061a08d5477bc580204c91dde8f01da195e95dd60ade209492 name: azurefile-csi-driver urls: - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/v1.0.0/azurefile-csi-driver-v1.0.0.tgz version: v1.0.0 -generated: "2023-02-10T02:47:55.452013107Z" + - apiVersion: v1 + appVersion: latest + created: "2023-02-10T02:49:15.110255075Z" + description: Azure File Container Storage Interface (CSI) Storage Plugin + digest: ab227c1dd2044b46fcb6c397ec393ab2b0f5364661df9e2664f562c4848232af + name: azurefile-csi-driver + urls: + - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/latest/azurefile-csi-driver-v0.0.0.tgz + version: v0.0.0 +generated: "2023-02-10T02:49:15.1090849Z" diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..5a20f062ae102aeb2e67e43df52b2b5c7e8f7cb5 GIT binary patch literal 11432 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 literal 0 HcmV?d00001 diff --git a/charts/latest/azurefile-csi-driver-v1.26.0.tgz b/charts/latest/azurefile-csi-driver-v1.26.0.tgz deleted file mode 100644 index 29a2d7c4b3732c2e5f62dbb6abe6d496c5a62751..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11417 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 z z(u_s&n75W3*-?A$8jZu)e$~_*_st*nx>GhZE`rzfb12-#HS}ET<$&hgtS;wm=EHRp zv9!!I?~Zn6KQ4`y#!@QV%*CeMX9jsRPQlLia-xVB*(!9NaCEzR(P z4P9$3z_t8NFyw_=5Fx;{XrXCALAyWuMRGO`MLk3~ZTx|SOK&xhk!2)Xcmk?3X|yTv zY9_B0Tt9zBCpeJ@X3B%HgZy;7{&xpNf_-iaC&10AmVK|=8tJ4t!8=vDzTd3J#@P3( zbnF`Fa$6cE)gmQYd+pAwZNbZsK`i|NJw)BK{@~}66LZUdMiZ?!K!qj%avPDiSaP&G z&go~w>xxxzF;a^o&r0_zDv!5Y2RlZ!X)xN^uDW(}?RZhu$gbl;k8Rx*01vf_d>kSf zOYaW4<_F*_=2rVCUfY`WkK{Ug`;f+7aI0^BxFQ32AKnXiAfzZA77Vs>?1=%}9nx)q z8DY{?EqfA*N>mmzuLHS9{-pPO0LQteYwt0KDTK~X0@kH(Og^?5w!pmK&#nUO4!t-( z6bB-6j)eCbJ3m=S5cG<{5pYBId3Y>_|6EO}mKiVGPqAV-!dn^9SEsrEzPun<_@4_I O{Pt*M1n~zF;{O0w+Q|O^ diff --git a/charts/latest/azurefile-csi-driver/Chart.yaml b/charts/latest/azurefile-csi-driver/Chart.yaml index c30547c2df..27ff7d757c 100644 --- a/charts/latest/azurefile-csi-driver/Chart.yaml +++ b/charts/latest/azurefile-csi-driver/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: v1.26.0 +appVersion: latest description: Azure File Container Storage Interface (CSI) Storage Plugin name: azurefile-csi-driver -version: v1.26.0 +version: v0.0.0 diff --git a/charts/latest/azurefile-csi-driver/values.yaml b/charts/latest/azurefile-csi-driver/values.yaml index 043a5ad872..50f8a7c731 100644 --- a/charts/latest/azurefile-csi-driver/values.yaml +++ b/charts/latest/azurefile-csi-driver/values.yaml @@ -1,8 +1,8 @@ image: baseRepo: mcr.microsoft.com azurefile: - repository: /oss/kubernetes-csi/azurefile-csi - tag: v1.26.0 + repository: /k8s/csi/azurefile-csi + tag: latest pullPolicy: IfNotPresent csiProvisioner: repository: /oss/kubernetes-csi/csi-provisioner diff --git a/deploy/csi-azurefile-controller.yaml b/deploy/csi-azurefile-controller.yaml index 4e711568da..623890f3ee 100644 --- a/deploy/csi-azurefile-controller.yaml +++ b/deploy/csi-azurefile-controller.yaml @@ -133,7 +133,7 @@ spec: cpu: 10m memory: 20Mi - name: azurefile - image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.0 + image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest imagePullPolicy: IfNotPresent args: - "--v=5" diff --git a/deploy/csi-azurefile-driver.yaml b/deploy/csi-azurefile-driver.yaml index 3b5fb795fc..55d31ed2d1 100644 --- a/deploy/csi-azurefile-driver.yaml +++ b/deploy/csi-azurefile-driver.yaml @@ -4,7 +4,7 @@ kind: CSIDriver metadata: name: file.csi.azure.com annotations: - csiDriver: v1.26.0 + csiDriver: latest snapshot: v5.0.1 spec: attachRequired: false diff --git a/deploy/csi-azurefile-node-windows.yaml b/deploy/csi-azurefile-node-windows.yaml index 82eaf817f4..9340864653 100644 --- a/deploy/csi-azurefile-node-windows.yaml +++ b/deploy/csi-azurefile-node-windows.yaml @@ -91,7 +91,7 @@ spec: cpu: 30m memory: 40Mi - name: azurefile - image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.0 + image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest imagePullPolicy: IfNotPresent args: - --v=5 diff --git a/deploy/csi-azurefile-node.yaml b/deploy/csi-azurefile-node.yaml index 66f858c7bd..f36a6a9545 100644 --- a/deploy/csi-azurefile-node.yaml +++ b/deploy/csi-azurefile-node.yaml @@ -82,7 +82,7 @@ spec: cpu: 10m memory: 20Mi - name: azurefile - image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.0 + image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest imagePullPolicy: IfNotPresent args: - "--v=5" From b26fa5179b072c72ba27b5a37af8913ec1212716 Mon Sep 17 00:00:00 2001 From: Andy Zhang Date: Sun, 12 Feb 2023 19:54:12 +0800 Subject: [PATCH 019/109] chore: switch master branch version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ea4fb0f30f..db8a1cf572 100755 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ GIT_COMMIT ?= $(shell git rev-parse HEAD) REGISTRY ?= andyzhangx REGISTRY_NAME ?= $(shell echo $(REGISTRY) | sed "s/.azurecr.io//g") IMAGE_NAME ?= azurefile-csi -IMAGE_VERSION ?= v1.25.0 +IMAGE_VERSION ?= v1.26.0 # Use a custom version for E2E tests if we are testing in CI ifdef CI ifndef PUBLISH From 85529baf7bbc08f93348463efa3957803b182ea9 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Sun, 12 Feb 2023 12:20:23 +0000 Subject: [PATCH 020/109] fix: remove forceUmount and lazyUmount --- pkg/azurefile/azure_common_linux.go | 31 +---------------------------- pkg/mounter/safe_mounter_unix.go | 9 +-------- 2 files changed, 2 insertions(+), 38 deletions(-) diff --git a/pkg/azurefile/azure_common_linux.go b/pkg/azurefile/azure_common_linux.go index 5b1eefbd48..3e3a5a9e9c 100644 --- a/pkg/azurefile/azure_common_linux.go +++ b/pkg/azurefile/azure_common_linux.go @@ -20,12 +20,6 @@ limitations under the License. package azurefile import ( - "fmt" - "os/exec" - "strings" - "time" - - "k8s.io/klog/v2" mount "k8s.io/mount-utils" ) @@ -34,21 +28,7 @@ func SMBMount(m *mount.SafeFormatAndMount, source, target, fsType string, option } func CleanupMountPoint(m *mount.SafeFormatAndMount, target string, extensiveMountCheck bool) error { - var err error - extensiveMountPointCheck := true - forceUnmounter, ok := m.Interface.(mount.MounterForceUnmounter) - if ok { - klog.V(2).Infof("force unmount on %s", target) - err = mount.CleanupMountWithForce(target, forceUnmounter, extensiveMountPointCheck, 30*time.Second) - } else { - err = mount.CleanupMountPoint(target, m.Interface, extensiveMountPointCheck) - } - - if err != nil && strings.Contains(err.Error(), "target is busy") { - klog.Warningf("unmount on %s failed with %v, try lazy unmount", target, err) - err = forceUmount(target) - } - return err + return mount.CleanupMountPoint(target, m.Interface, true /*extensiveMountPointCheck*/) } func preparePublishPath(path string, m *mount.SafeFormatAndMount) error { @@ -58,12 +38,3 @@ func preparePublishPath(path string, m *mount.SafeFormatAndMount) error { func prepareStagePath(path string, m *mount.SafeFormatAndMount) error { return nil } - -func forceUmount(path string) error { - cmd := exec.Command("umount", "-lf", path) - out, cmderr := cmd.CombinedOutput() - if cmderr != nil { - return fmt.Errorf("lazy unmount on %s failed with %v, output: %s", path, cmderr, string(out)) - } - return nil -} diff --git a/pkg/mounter/safe_mounter_unix.go b/pkg/mounter/safe_mounter_unix.go index 9b492fd451..d5ee4d14a8 100644 --- a/pkg/mounter/safe_mounter_unix.go +++ b/pkg/mounter/safe_mounter_unix.go @@ -20,20 +20,13 @@ limitations under the License. package mounter import ( - "runtime" - mount "k8s.io/mount-utils" utilexec "k8s.io/utils/exec" ) func NewSafeMounter() (*mount.SafeFormatAndMount, error) { - mounter := mount.New("") - if runtime.GOOS == "linux" { - // MounterForceUnmounter is only implemented on Linux now - mounter = mounter.(mount.MounterForceUnmounter) - } return &mount.SafeFormatAndMount{ - Interface: mounter, + Interface: mount.New(""), Exec: utilexec.New(), }, nil } From 14a2f6c0a613934b0fd322d4b824714e463b1706 Mon Sep 17 00:00:00 2001 From: Andy Zhang Date: Wed, 15 Feb 2023 20:11:02 +0800 Subject: [PATCH 021/109] Update csi-debug.md --- docs/csi-debug.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/csi-debug.md b/docs/csi-debug.md index d6c2f34472..498934fed0 100644 --- a/docs/csi-debug.md +++ b/docs/csi-debug.md @@ -172,5 +172,4 @@ Azure premium files follows provisioned model where IOPS and throughput are asso ##### For more, refer to this doc for perforance troubleshooting tips - [Link to performance troubleshooting tips](https://docs.microsoft.com/en-us/azure/storage/files/storage-troubleshooting-files-performance) -##### [Troubleshoot AKS Storage-related issues](https://docs.microsoft.com/en-us/troubleshoot/azure/azure-kubernetes/fail-to-mount-azure-file-share) ##### [Storage considerations for Azure Kubernetes Service (AKS)](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/scenarios/app-platform/aks/storage) From 5d5ef9d976fb6db3660e636b339dd887de602413 Mon Sep 17 00:00:00 2001 From: Andy Zhang Date: Wed, 15 Feb 2023 20:13:55 +0800 Subject: [PATCH 022/109] Update csi-debug.md --- docs/csi-debug.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/csi-debug.md b/docs/csi-debug.md index 498934fed0..dc6a1cb1fb 100644 --- a/docs/csi-debug.md +++ b/docs/csi-debug.md @@ -153,6 +153,7 @@ mount -v -t nfs -o vers=4,minorversion=1,sec=sys accountname.file.core.windows.n ``` - [Troubleshoot Azure File mount issues on AKS](http://aka.ms/filemounterror) + - [Troubleshoot Azure Files problems in Linux (SMB)](https://learn.microsoft.com/en-us/azure/storage/files/storage-troubleshoot-linux-file-connection-problems) ### Troubleshooting performance issues on Azure Files From f73c154f79286a3a2d7f831c6a6161a86c95e7bc Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Thu, 16 Feb 2023 08:01:08 +0000 Subject: [PATCH 023/109] doc: cut v1.26.1 release --- README.md | 2 +- charts/README.md | 2 +- charts/index.yaml | 85 ++- charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 11432 -> 0 bytes .../latest/azurefile-csi-driver-v1.26.1.tgz | Bin 0 -> 11419 bytes charts/latest/azurefile-csi-driver/Chart.yaml | 4 +- .../latest/azurefile-csi-driver/values.yaml | 4 +- .../v1.26.1/azurefile-csi-driver-v1.26.1.tgz | Bin 0 -> 11417 bytes .../v1.26.1/azurefile-csi-driver/Chart.yaml | 5 + .../azurefile-csi-driver/templates/NOTES.txt | 5 + .../templates/_helpers.tpl | 49 ++ .../templates/crd-csi-snapshot.yaml | 661 ++++++++++++++++++ .../templates/csi-azurefile-controller.yaml | 243 +++++++ .../templates/csi-azurefile-driver.yaml | 17 + .../templates/csi-azurefile-node-windows.yaml | 222 ++++++ .../templates/csi-azurefile-node.yaml | 217 ++++++ .../templates/csi-snapshot-controller.yaml | 65 ++ .../rbac-csi-azurefile-controller.yaml | 207 ++++++ .../templates/rbac-csi-azurefile-node.yaml | 29 + .../rbac-csi-snapshot-controller.yaml | 80 +++ ...rviceaccount-csi-azurefile-controller.yaml | 9 + .../serviceaccount-csi-azurefile-node.yaml | 9 + ...erviceaccount-csi-snapshot-controller.yaml | 9 + .../v1.26.1/azurefile-csi-driver/values.yaml | 254 +++++++ deploy/csi-azurefile-controller.yaml | 2 +- deploy/csi-azurefile-driver.yaml | 2 +- deploy/csi-azurefile-node-windows.yaml | 2 +- deploy/csi-azurefile-node.yaml | 2 +- deploy/v1.26.1/crd-csi-snapshot.yaml | 659 +++++++++++++++++ deploy/v1.26.1/csi-azurefile-controller.yaml | 184 +++++ deploy/v1.26.1/csi-azurefile-driver.yaml | 15 + .../v1.26.1/csi-azurefile-node-windows.yaml | 181 +++++ deploy/v1.26.1/csi-azurefile-node.yaml | 157 +++++ deploy/v1.26.1/csi-snapshot-controller.yaml | 46 ++ .../rbac-csi-azurefile-controller.yaml | 194 +++++ deploy/v1.26.1/rbac-csi-azurefile-node.yaml | 30 + .../v1.26.1/rbac-csi-snapshot-controller.yaml | 78 +++ docs/install-azurefile-csi-driver.md | 2 +- docs/install-csi-driver-v1.26.1.md | 45 ++ 39 files changed, 3728 insertions(+), 49 deletions(-) delete mode 100644 charts/latest/azurefile-csi-driver-v0.0.0.tgz create mode 100644 charts/latest/azurefile-csi-driver-v1.26.1.tgz create mode 100644 charts/v1.26.1/azurefile-csi-driver-v1.26.1.tgz create mode 100644 charts/v1.26.1/azurefile-csi-driver/Chart.yaml create mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/NOTES.txt create mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/_helpers.tpl create mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/crd-csi-snapshot.yaml create mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-controller.yaml create mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-driver.yaml create mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml create mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node.yaml create mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/csi-snapshot-controller.yaml create mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml create mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml create mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml create mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml create mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml create mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml create mode 100644 charts/v1.26.1/azurefile-csi-driver/values.yaml create mode 100644 deploy/v1.26.1/crd-csi-snapshot.yaml create mode 100644 deploy/v1.26.1/csi-azurefile-controller.yaml create mode 100644 deploy/v1.26.1/csi-azurefile-driver.yaml create mode 100644 deploy/v1.26.1/csi-azurefile-node-windows.yaml create mode 100644 deploy/v1.26.1/csi-azurefile-node.yaml create mode 100644 deploy/v1.26.1/csi-snapshot-controller.yaml create mode 100644 deploy/v1.26.1/rbac-csi-azurefile-controller.yaml create mode 100644 deploy/v1.26.1/rbac-csi-azurefile-node.yaml create mode 100644 deploy/v1.26.1/rbac-csi-snapshot-controller.yaml create mode 100644 docs/install-csi-driver-v1.26.1.md diff --git a/README.md b/README.md index c13994114e..70ac4ed99c 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Disclaimer: Deploying this driver manually is not an officially supported Micros |Driver Version |Image | supported k8s version | |----------------|---------------------------------------------------------- |-----------------------| |master branch |mcr.microsoft.com/k8s/csi/azurefile-csi:latest | 1.21+ | -|v1.26.0 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.0 | 1.21+ | +|v1.26.1 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.1 | 1.21+ | |v1.25.1 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.25.1 | 1.21+ | |v1.24.0 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.24.0 | 1.21+ | diff --git a/charts/README.md b/charts/README.md index b2ff7adb29..5b60f5683d 100644 --- a/charts/README.md +++ b/charts/README.md @@ -16,7 +16,7 @@ ### install a specific version ```console helm repo add azurefile-csi-driver https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts -helm install azurefile-csi-driver azurefile-csi-driver/azurefile-csi-driver --namespace kube-system --version v1.26.0 +helm install azurefile-csi-driver azurefile-csi-driver/azurefile-csi-driver --namespace kube-system --version v1.26.1 ``` ### install on RedHat/CentOS diff --git a/charts/index.yaml b/charts/index.yaml index f79db5d256..6876525a8d 100644 --- a/charts/index.yaml +++ b/charts/index.yaml @@ -1,9 +1,27 @@ apiVersion: v1 entries: azurefile-csi-driver: + - apiVersion: v1 + appVersion: v1.26.1 + created: "2023-02-16T07:31:47.255463147Z" + description: Azure File Container Storage Interface (CSI) Storage Plugin + digest: c7bf2a1b9c03c4281b038c5341489b63a98d0353be4fa3518df0c4ad2917531c + name: azurefile-csi-driver + urls: + - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/latest/azurefile-csi-driver-v1.26.1.tgz + version: v1.26.1 + - apiVersion: v1 + appVersion: v1.26.1 + created: "2023-02-16T07:31:47.28183659Z" + description: Azure File Container Storage Interface (CSI) Storage Plugin + digest: b1c78e2c38869f9430f3e2e671fb168db803eab2fbc0ef905eacdf8794d7968a + name: azurefile-csi-driver + urls: + - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/v1.26.1/azurefile-csi-driver-v1.26.1.tgz + version: v1.26.1 - apiVersion: v1 appVersion: v1.26.0 - created: "2023-02-10T02:49:15.131414709Z" + created: "2023-02-16T07:31:47.280446108Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 98d15a8ced671a7c3d9aec8ebe00b58abeecb5f65ab966c9c01c4f39121adc0c name: azurefile-csi-driver @@ -12,7 +30,7 @@ entries: version: v1.26.0 - apiVersion: v1 appVersion: v1.25.1 - created: "2023-02-10T02:49:15.130456807Z" + created: "2023-02-16T07:31:47.278883544Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 2bf374cc321c5bc8e76e06cd5df85ce7d7d14574397e7e7f7173077393f554c4 name: azurefile-csi-driver @@ -21,7 +39,7 @@ entries: version: v1.25.1 - apiVersion: v1 appVersion: v1.25.0 - created: "2023-02-10T02:49:15.129444021Z" + created: "2023-02-16T07:31:47.277769098Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: ba80dcd23dade4e62b39d3dc638c599e9d5e100009fa14d4164bfc8966fea3dd name: azurefile-csi-driver @@ -30,7 +48,7 @@ entries: version: v1.25.0 - apiVersion: v1 appVersion: v1.24.0 - created: "2023-02-10T02:49:15.128438281Z" + created: "2023-02-16T07:31:47.276565346Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 1905eb862745d4a7f57c5de96848cee194adf827086984b75bcaefce5c90142b name: azurefile-csi-driver @@ -39,7 +57,7 @@ entries: version: v1.24.0 - apiVersion: v1 appVersion: v1.23.0 - created: "2023-02-10T02:49:15.126899719Z" + created: "2023-02-16T07:31:47.275520175Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 5fcb33617d16e90df1e7041b0df02e5bd92595e86381db30d356b0b2e3500bc4 name: azurefile-csi-driver @@ -48,7 +66,7 @@ entries: version: v1.23.0 - apiVersion: v1 appVersion: v1.22.0 - created: "2023-02-10T02:49:15.125674354Z" + created: "2023-02-16T07:31:47.274026567Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 253d87a8b876dbdd55870a7fee88547393179d03f193661125f5a0b63411f922 name: azurefile-csi-driver @@ -57,7 +75,7 @@ entries: version: v1.22.0 - apiVersion: v1 appVersion: v1.21.0 - created: "2023-02-10T02:49:15.124674922Z" + created: "2023-02-16T07:31:47.272403178Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: d45bf3455ebadc9cc5afaf9da66aa1ea1d4b719cfdff5af661f93bb26c01a504 name: azurefile-csi-driver @@ -66,7 +84,7 @@ entries: version: v1.21.0 - apiVersion: v1 appVersion: v1.20.0 - created: "2023-02-10T02:49:15.123744091Z" + created: "2023-02-16T07:31:47.271424231Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 7cc43d57a79137aea5414fb51a9bbd77bb679b29ee49c06865c1a5b9ba60be99 name: azurefile-csi-driver @@ -75,7 +93,7 @@ entries: version: v1.20.0 - apiVersion: v1 appVersion: v1.19.0 - created: "2023-02-10T02:49:15.122285936Z" + created: "2023-02-16T07:31:47.269853632Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 18f6efbed424efd661fde43be2e5a48a5012a46a7938c33b36963cbd9875a5af name: azurefile-csi-driver @@ -84,7 +102,7 @@ entries: version: v1.19.0 - apiVersion: v1 appVersion: v1.18.0 - created: "2023-02-10T02:49:15.120528972Z" + created: "2023-02-16T07:31:47.268762331Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 696ca23d9ee517f71ef5e852955c8d0f1017c331c025426c6fcbe7a06d006c66 name: azurefile-csi-driver @@ -93,7 +111,7 @@ entries: version: v1.18.0 - apiVersion: v1 appVersion: v1.17.0 - created: "2023-02-10T02:49:15.1196304Z" + created: "2023-02-16T07:31:47.267668616Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 5632f61265a3b78dce3e2b15e07cc9b14a7f54a778878c02ca2d9fe69ca0344e name: azurefile-csi-driver @@ -102,7 +120,7 @@ entries: version: v1.17.0 - apiVersion: v1 appVersion: v1.16.0 - created: "2023-02-10T02:49:15.118707997Z" + created: "2023-02-16T07:31:47.265715467Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: a7a2d57e8eca7dc06c8b2cffb9bccb857753eb110b8e70760b3e04f4e6a87552 name: azurefile-csi-driver @@ -111,7 +129,7 @@ entries: version: v1.16.0 - apiVersion: v1 appVersion: v1.15.0 - created: "2023-02-10T02:49:15.117817743Z" + created: "2023-02-16T07:31:47.264535319Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: c1a31dadce233a90c19dce70f6cc92ba2e20bbaa1b1883baea72381d09303118 name: azurefile-csi-driver @@ -120,7 +138,7 @@ entries: version: v1.15.0 - apiVersion: v1 appVersion: v1.14.0 - created: "2023-02-10T02:49:15.116852798Z" + created: "2023-02-16T07:31:47.263472933Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 0c9ad4afa5ebfdb2851ad93eb16a0382d61448714b7556899360730a2fdf463a name: azurefile-csi-driver @@ -129,7 +147,7 @@ entries: version: v1.14.0 - apiVersion: v1 appVersion: v1.13.0 - created: "2023-02-10T02:49:15.115929349Z" + created: "2023-02-16T07:31:47.26241761Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 214042b029d858b50a0f8bba33a7aa2b41d1b67bce16f957ca183ae7438dac3f name: azurefile-csi-driver @@ -138,7 +156,7 @@ entries: version: v1.13.0 - apiVersion: v1 appVersion: v1.12.0 - created: "2023-02-10T02:49:15.114589222Z" + created: "2023-02-16T07:31:47.261429446Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: fbd63929671066a26df898d32282a6e79c39499a39c71761c546d069459d847d name: azurefile-csi-driver @@ -147,7 +165,7 @@ entries: version: v1.12.0 - apiVersion: v1 appVersion: v1.11.0 - created: "2023-02-10T02:49:15.113369009Z" + created: "2023-02-16T07:31:47.260310022Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 76bd438f8391d08235b09fbca859f25a9fcf8e018fd1e7e33444ca9ea946ce4b name: azurefile-csi-driver @@ -156,7 +174,7 @@ entries: version: v1.11.0 - apiVersion: v1 appVersion: v1.10.0 - created: "2023-02-10T02:49:15.112179371Z" + created: "2023-02-16T07:31:47.25827465Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 845a9de8b571b255d05ae9c643d9b90a57fe6507ff3fb735c88b41f99f6f28dc name: azurefile-csi-driver @@ -165,7 +183,7 @@ entries: version: v1.10.0 - apiVersion: v1 appVersion: v1.9.0 - created: "2023-02-10T02:49:15.137574748Z" + created: "2023-02-16T07:31:47.289624439Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 59a8057fbbd6d59919b84ef0c3396d5a0a46d1f29df604457db676f4af63c714 name: azurefile-csi-driver @@ -174,7 +192,7 @@ entries: version: v1.9.0 - apiVersion: v1 appVersion: v1.8.0 - created: "2023-02-10T02:49:15.136616431Z" + created: "2023-02-16T07:31:47.288267649Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 455b7c342194311046df526d10926d94f3bef24f753a07003fb1cad211c4cb52 name: azurefile-csi-driver @@ -183,7 +201,7 @@ entries: version: v1.8.0 - apiVersion: v1 appVersion: v1.7.0 - created: "2023-02-10T02:49:15.135630744Z" + created: "2023-02-16T07:31:47.286190248Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 057b3f6ef6001d3457fbffc27f90316c981a089696abd3d38bcc8de5537dfa6f name: azurefile-csi-driver @@ -192,7 +210,7 @@ entries: version: v1.7.0 - apiVersion: v1 appVersion: v1.6.0 - created: "2023-02-10T02:49:15.1348858Z" + created: "2023-02-16T07:31:47.284961365Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: cc2a0dda824cdda4e8141e26878bbb481c5a52e45785a5dbf72e54f2a376e522 name: azurefile-csi-driver @@ -201,7 +219,7 @@ entries: version: v1.6.0 - apiVersion: v1 appVersion: v1.5.0 - created: "2023-02-10T02:49:15.134137781Z" + created: "2023-02-16T07:31:47.284057281Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 2258177477415ddecd83dc46dfd88833223623224c7fe396590b617082bcd845 name: azurefile-csi-driver @@ -210,7 +228,7 @@ entries: version: v1.5.0 - apiVersion: v1 appVersion: v1.4.0 - created: "2023-02-10T02:49:15.132561785Z" + created: "2023-02-16T07:31:47.283241837Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 40e9bc4ee187789166fcb7c3c82b85b33ecd3a6096266fe74e411d6b48961ece name: azurefile-csi-driver @@ -219,7 +237,7 @@ entries: version: v1.4.0 - apiVersion: v1 appVersion: v1.3.0 - created: "2023-02-10T02:49:15.131929231Z" + created: "2023-02-16T07:31:47.282436878Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 12942f422b7cccbfe950bbdbd5c844f5ae4b7c292f32389cba312730a6fe9a62 name: azurefile-csi-driver @@ -228,7 +246,7 @@ entries: version: v1.3.0 - apiVersion: v1 appVersion: v1.2.0 - created: "2023-02-10T02:49:15.12282244Z" + created: "2023-02-16T07:31:47.270436553Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: b62f44b757416a9e1f5a91e19285f5f5056ec6068802dd9cd82373bef40c9ee9 name: azurefile-csi-driver @@ -237,7 +255,7 @@ entries: version: v1.2.0 - apiVersion: v1 appVersion: v1.1.0 - created: "2023-02-10T02:49:15.111266014Z" + created: "2023-02-16T07:31:47.257101093Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 675d96b309a1c5c491053ebbb854c046737420929c4f0692839afdaaf0db3933 name: azurefile-csi-driver @@ -246,20 +264,11 @@ entries: version: v1.1.0 - apiVersion: v1 appVersion: v1.0.0 - created: "2023-02-10T02:49:15.110779468Z" + created: "2023-02-16T07:31:47.256399049Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 6fd5e54e949ef1061a08d5477bc580204c91dde8f01da195e95dd60ade209492 name: azurefile-csi-driver urls: - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/v1.0.0/azurefile-csi-driver-v1.0.0.tgz version: v1.0.0 - - apiVersion: v1 - appVersion: latest - created: "2023-02-10T02:49:15.110255075Z" - description: Azure File Container Storage Interface (CSI) Storage Plugin - digest: ab227c1dd2044b46fcb6c397ec393ab2b0f5364661df9e2664f562c4848232af - name: azurefile-csi-driver - urls: - - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/latest/azurefile-csi-driver-v0.0.0.tgz - version: v0.0.0 -generated: "2023-02-10T02:49:15.1090849Z" +generated: "2023-02-16T07:31:47.254265709Z" diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz deleted file mode 100644 index 5a20f062ae102aeb2e67e43df52b2b5c7e8f7cb5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11432 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 diff --git a/charts/latest/azurefile-csi-driver-v1.26.1.tgz b/charts/latest/azurefile-csi-driver-v1.26.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..d03a27174db258d974565f4028fcd00ebaab3bc9 GIT binary patch literal 11419 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 BpP~Q& literal 0 HcmV?d00001 diff --git a/charts/latest/azurefile-csi-driver/Chart.yaml b/charts/latest/azurefile-csi-driver/Chart.yaml index 27ff7d757c..630811bca8 100644 --- a/charts/latest/azurefile-csi-driver/Chart.yaml +++ b/charts/latest/azurefile-csi-driver/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: latest +appVersion: v1.26.1 description: Azure File Container Storage Interface (CSI) Storage Plugin name: azurefile-csi-driver -version: v0.0.0 +version: v1.26.1 diff --git a/charts/latest/azurefile-csi-driver/values.yaml b/charts/latest/azurefile-csi-driver/values.yaml index 50f8a7c731..f290d24ee6 100644 --- a/charts/latest/azurefile-csi-driver/values.yaml +++ b/charts/latest/azurefile-csi-driver/values.yaml @@ -1,8 +1,8 @@ image: baseRepo: mcr.microsoft.com azurefile: - repository: /k8s/csi/azurefile-csi - tag: latest + repository: /oss/kubernetes-csi/azurefile-csi + tag: v1.26.1 pullPolicy: IfNotPresent csiProvisioner: repository: /oss/kubernetes-csi/csi-provisioner diff --git a/charts/v1.26.1/azurefile-csi-driver-v1.26.1.tgz b/charts/v1.26.1/azurefile-csi-driver-v1.26.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..0b2623bf217c4eb906e5dc2450a33adc8b8608d6 GIT binary patch literal 11417 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 literal 0 HcmV?d00001 diff --git a/charts/v1.26.1/azurefile-csi-driver/Chart.yaml b/charts/v1.26.1/azurefile-csi-driver/Chart.yaml new file mode 100644 index 0000000000..630811bca8 --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +appVersion: v1.26.1 +description: Azure File Container Storage Interface (CSI) Storage Plugin +name: azurefile-csi-driver +version: v1.26.1 diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/NOTES.txt b/charts/v1.26.1/azurefile-csi-driver/templates/NOTES.txt new file mode 100644 index 0000000000..3fadd8ad36 --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/templates/NOTES.txt @@ -0,0 +1,5 @@ +The Azure File CSI Driver is getting deployed to your cluster. + +To check Azure File CSI Driver pods status, please run: + + kubectl --namespace={{ .Release.Namespace }} get pods --selector="release={{ .Release.Name }}" --watch diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/_helpers.tpl b/charts/v1.26.1/azurefile-csi-driver/templates/_helpers.tpl new file mode 100644 index 0000000000..b1bf4dc1b6 --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/templates/_helpers.tpl @@ -0,0 +1,49 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* Expand the name of the chart.*/}} +{{- define "azurefile.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "azurefile.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common selectors. +*/}} +{{- define "azurefile.selectorLabels" -}} +app.kubernetes.io/name: {{ template "azurefile.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Common labels. +*/}} +{{- define "azurefile.labels" -}} +{{- include "azurefile.selectorLabels" . }} +app.kubernetes.io/component: csi-driver +app.kubernetes.io/part-of: {{ template "azurefile.name" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +helm.sh/chart: {{ template "azurefile.chart" . }} +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels }} +{{- end }} +{{- end -}} + + +{{/* pull secrets for containers */}} +{{- define "azurefile.pullSecrets" -}} +{{- if .Values.imagePullSecrets }} +imagePullSecrets: +{{- range .Values.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} +{{- end -}} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/crd-csi-snapshot.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/crd-csi-snapshot.yaml new file mode 100644 index 0000000000..b0e29453c5 --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/templates/crd-csi-snapshot.yaml @@ -0,0 +1,661 @@ +{{- if .Values.snapshot.enabled -}} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + creationTimestamp: null + name: volumesnapshots.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshot + listKind: VolumeSnapshotList + plural: volumesnapshots + shortNames: + - vs + singular: volumesnapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' + properties: + source: + description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. + type: string + type: object + oneOf: + - required: ["persistentVolumeClaimName"] + - required: ["volumeSnapshotContentName"] + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurrs during the snapshot creation. Upon success, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + type: string + description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshot is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshot" + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' + properties: + source: + description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurrs during the snapshot creation. Upon success, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + type: string + description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + creationTimestamp: null + name: volumesnapshotclasses.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotClass + listKind: VolumeSnapshotClassList + plural: volumesnapshotclasses + shortNames: + - vsclass + - vsclasses + singular: volumesnapshotclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotClass is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotClass" + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + creationTimestamp: null + name: volumesnapshotcontents.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotContent + listKind: VolumeSnapshotContentList + plural: volumesnapshotcontents + shortNames: + - vsc + - vscs + singular: volumesnapshotcontent + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. + type: string + type: object + oneOf: + - required: ["snapshotHandle"] + - required: ["volumeHandle"] + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotContent is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotContent" + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. + type: string + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-controller.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-controller.yaml new file mode 100644 index 0000000000..23381ec245 --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-controller.yaml @@ -0,0 +1,243 @@ +kind: Deployment +apiVersion: apps/v1 +metadata: + name: {{ .Values.controller.name }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Values.controller.name }} + {{- include "azurefile.labels" . | nindent 4 }} +{{- with .Values.controller.labels }} +{{ . | toYaml | indent 4 }} +{{- end }} +{{- with .Values.controller.annotations }} + annotations: +{{ . | toYaml | indent 4 }} +{{- end }} +spec: + replicas: {{ .Values.controller.replicas }} + selector: + matchLabels: + {{- include "azurefile.selectorLabels" . | nindent 6 }} + app: {{ .Values.controller.name }} + template: + metadata: + labels: + {{- include "azurefile.labels" . | nindent 8 }} + app: {{ .Values.controller.name }} +{{- with .Values.controller.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.controller.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + spec: + hostNetwork: {{ .Values.controller.hostNetwork }} + serviceAccountName: {{ .Values.serviceAccount.controller }} + nodeSelector: + kubernetes.io/os: linux +{{- with .Values.controller.nodeSelector }} +{{ toYaml . | indent 8 }} +{{- end }} + {{- if .Values.controller.runOnMaster}} + node-role.kubernetes.io/master: "" + {{- end}} + {{- if .Values.controller.runOnControlPlane}} + node-role.kubernetes.io/control-plane: "" + {{- end}} + priorityClassName: system-cluster-critical +{{- with .Values.controller.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.controller.affinity }} + affinity: +{{ toYaml . | indent 8 }} +{{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + containers: + - name: csi-provisioner +{{- if hasPrefix "/" .Values.image.csiProvisioner.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.csiProvisioner.repository }}:{{ .Values.image.csiProvisioner.tag }}" +{{- else }} + image: "{{ .Values.image.csiProvisioner.repository }}:{{ .Values.image.csiProvisioner.tag }}" +{{- end }} + args: + - "-v=2" + - "--csi-address=$(ADDRESS)" + - "--leader-election" + - "--leader-election-namespace={{ .Release.Namespace }}" + - "--timeout=300s" + - "--extra-create-metadata=true" + - "--kube-api-qps=50" + - "--kube-api-burst=100" + env: + - name: ADDRESS + value: /csi/csi.sock + imagePullPolicy: {{ .Values.image.csiProvisioner.pullPolicy }} + volumeMounts: + - mountPath: /csi + name: socket-dir + resources: {{- toYaml .Values.controller.resources.csiProvisioner | nindent 12 }} + - name: csi-attacher +{{- if hasPrefix "/" .Values.image.csiAttacher.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.csiAttacher.repository }}:{{ .Values.image.csiAttacher.tag }}" +{{- else }} + image: "{{ .Values.image.csiAttacher.repository }}:{{ .Values.image.csiAttacher.tag }}" +{{- end }} + args: + - "-v=2" + - "-csi-address=$(ADDRESS)" + - "-timeout=120s" + - "-leader-election" + - "--leader-election-namespace={{ .Release.Namespace }}" + - "--kube-api-qps=50" + - "--kube-api-burst=100" + env: + - name: ADDRESS + value: /csi/csi.sock + imagePullPolicy: {{ .Values.image.csiAttacher.pullPolicy }} + volumeMounts: + - mountPath: /csi + name: socket-dir + resources: {{- toYaml .Values.controller.resources.csiAttacher | nindent 12 }} + - name: csi-snapshotter +{{- if hasPrefix "/" .Values.snapshot.image.csiSnapshotter.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.snapshot.image.csiSnapshotter.repository }}:{{ .Values.snapshot.image.csiSnapshotter.tag }}" +{{- else }} + image: "{{ .Values.snapshot.image.csiSnapshotter.repository }}:{{ .Values.snapshot.image.csiSnapshotter.tag }}" +{{- end }} + args: + - "-csi-address=$(ADDRESS)" + - "-leader-election" + - "--leader-election-namespace={{ .Release.Namespace }}" + - "-v=2" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /csi + resources: {{- toYaml .Values.controller.resources.csiSnapshotter | nindent 12 }} + - name: csi-resizer +{{- if hasPrefix "/" .Values.image.csiResizer.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.csiResizer.repository }}:{{ .Values.image.csiResizer.tag }}" +{{- else }} + image: "{{ .Values.image.csiResizer.repository }}:{{ .Values.image.csiResizer.tag }}" +{{- end }} + args: + - "-csi-address=$(ADDRESS)" + - "-v=2" + - "-leader-election" + - "--leader-election-namespace={{ .Release.Namespace }}" + - '-handle-volume-inuse-error=false' + - '-timeout=120s' + - '-feature-gates=RecoverVolumeExpansionFailure=true' + env: + - name: ADDRESS + value: /csi/csi.sock + imagePullPolicy: {{ .Values.image.csiResizer.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /csi + resources: {{- toYaml .Values.controller.resources.csiResizer | nindent 12 }} + - name: liveness-probe +{{- if hasPrefix "/" .Values.image.livenessProbe.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- else }} + image: "{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- end }} + args: + - --csi-address=/csi/csi.sock + - --probe-timeout=3s + - --health-port={{ .Values.controller.livenessProbe.healthPort }} + - --v=2 + imagePullPolicy: {{ .Values.image.livenessProbe.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /csi + resources: {{- toYaml .Values.controller.resources.livenessProbe | nindent 12 }} + - name: azurefile +{{- if hasPrefix "/" .Values.image.azurefile.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" +{{- else }} + image: "{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" +{{- end }} + args: + - "--v={{ .Values.controller.logLevel }}" + - "--endpoint=$(CSI_ENDPOINT)" + - "--metrics-address=0.0.0.0:{{ .Values.controller.metricsPort }}" + - "--kubeconfig={{ .Values.controller.kubeconfig }}" + - "--drivername={{ .Values.driver.name }}" + - "--cloud-config-secret-name={{ .Values.controller.cloudConfigSecretName }}" + - "--cloud-config-secret-namespace={{ .Values.controller.cloudConfigSecretNamespace }}" + - "--custom-user-agent={{ .Values.driver.customUserAgent }}" + - "--user-agent-suffix={{ .Values.driver.userAgentSuffix }}" + - "--allow-empty-cloud-config={{ .Values.controller.allowEmptyCloudConfig }}" + ports: + - containerPort: {{ .Values.controller.livenessProbe.healthPort }} + name: healthz + protocol: TCP + - containerPort: {{ .Values.controller.metricsPort }} + name: metrics + protocol: TCP + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + timeoutSeconds: 10 + periodSeconds: 30 + env: + - name: AZURE_CREDENTIAL_FILE + valueFrom: + configMapKeyRef: + name: azure-cred-file + key: path + optional: true + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + {{- if ne .Values.driver.httpsProxy "" }} + - name: HTTPS_PROXY + value: {{ .Values.driver.httpsProxy }} + {{- end }} + {{- if ne .Values.driver.httpProxy "" }} + - name: HTTP_PROXY + value: {{ .Values.driver.httpProxy }} + {{- end }} + - name: AZURE_GO_SDK_LOG_LEVEL + value: {{ .Values.driver.azureGoSDKLogLevel }} + imagePullPolicy: {{ .Values.image.azurefile.pullPolicy }} + volumeMounts: + - mountPath: /csi + name: socket-dir + - mountPath: /etc/kubernetes/ + name: azure-cred + {{- if eq .Values.linux.distro "fedora" }} + - name: ssl + mountPath: /etc/ssl/certs + readOnly: true + - name: ssl-pki + mountPath: /etc/pki/ca-trust/extracted + readOnly: true + {{- end }} + resources: {{- toYaml .Values.controller.resources.azurefile | nindent 12 }} + volumes: + - name: socket-dir + emptyDir: {} + - name: azure-cred + hostPath: + path: /etc/kubernetes/ + type: DirectoryOrCreate + {{- if eq .Values.linux.distro "fedora" }} + - name: ssl + hostPath: + path: /etc/ssl/certs + - name: ssl-pki + hostPath: + path: /etc/pki/ca-trust/extracted + {{- end }} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-driver.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-driver.yaml new file mode 100644 index 0000000000..e1facb056a --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-driver.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: {{ .Values.driver.name }} + labels: + {{- include "azurefile.labels" . | nindent 4 }} + annotations: + csiDriver: "{{ .Values.image.azurefile.tag }}" + snapshot: "{{ .Values.snapshot.image.csiSnapshotter.tag }}" +spec: + attachRequired: {{ .Values.controller.attachRequired }} + podInfoOnMount: true + volumeLifecycleModes: + - Persistent + - Ephemeral + fsGroupPolicy: ReadWriteOnceWithFSType diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml new file mode 100644 index 0000000000..813859aee0 --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml @@ -0,0 +1,222 @@ +{{- if .Values.windows.enabled}} +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: {{ .Values.windows.dsName }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Values.windows.dsName }} + {{- include "azurefile.labels" . | nindent 4 }} +{{- with .Values.windows.labels }} +{{ . | toYaml | indent 4 }} +{{- end }} +{{- with .Values.windows.annotations }} + annotations: +{{ . | toYaml | indent 4 }} +{{- end }} +spec: + updateStrategy: + rollingUpdate: + maxUnavailable: {{ .Values.node.maxUnavailable }} + type: RollingUpdate + selector: + matchLabels: + app: {{ .Values.windows.dsName }} + {{- include "azurefile.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + app: {{ .Values.windows.dsName }} + {{- include "azurefile.labels" . | nindent 8 }} +{{- with .Values.windows.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.windows.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + spec: + serviceAccountName: {{ .Values.serviceAccount.node }} +{{- with .Values.windows.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} +{{- end }} + nodeSelector: + kubernetes.io/os: windows +{{- with .Values.windows.nodeSelector }} +{{ toYaml . | indent 8 }} +{{- end }} + affinity: +{{- with .Values.windows.affinity }} +{{ toYaml . | indent 8 }} +{{- end }} + nodeAffinity: +{{ toYaml .Values.windows.nodeAffinity | indent 10 }} + priorityClassName: system-node-critical + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + containers: + - name: liveness-probe + volumeMounts: + - mountPath: C:\csi + name: plugin-dir +{{- if hasPrefix "/" .Values.image.livenessProbe.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- else }} + image: "{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- end }} + args: + - "--csi-address=$(CSI_ENDPOINT)" + - "--probe-timeout=3s" + - "--health-port={{ .Values.node.livenessProbe.healthPort }}" + - "--v=2" + env: + - name: CSI_ENDPOINT + value: unix://C:\\csi\\csi.sock + imagePullPolicy: {{ .Values.image.livenessProbe.pullPolicy }} + resources: {{- toYaml .Values.windows.resources.livenessProbe | nindent 12 }} + - name: node-driver-registrar +{{- if hasPrefix "/" .Values.image.nodeDriverRegistrar.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.nodeDriverRegistrar.repository }}:{{ .Values.image.nodeDriverRegistrar.tag }}" +{{- else }} + image: "{{ .Values.image.nodeDriverRegistrar.repository }}:{{ .Values.image.nodeDriverRegistrar.tag }}" +{{- end }} + args: + - "--csi-address=$(CSI_ENDPOINT)" + - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" + - "--v=2" + livenessProbe: + exec: + command: + - /csi-node-driver-registrar.exe + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --mode=kubelet-registration-probe + initialDelaySeconds: 60 + timeoutSeconds: 30 + env: + - name: CSI_ENDPOINT + value: unix://C:\\csi\\csi.sock + - name: DRIVER_REG_SOCK_PATH + value: C:\\var\\lib\\kubelet\\plugins\\{{ .Values.driver.name }}\\csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + imagePullPolicy: {{ .Values.image.nodeDriverRegistrar.pullPolicy }} + volumeMounts: + - name: kubelet-dir + mountPath: "C:\\var\\lib\\kubelet" + - name: plugin-dir + mountPath: C:\csi + - name: registration-dir + mountPath: C:\registration + resources: {{- toYaml .Values.windows.resources.nodeDriverRegistrar | nindent 12 }} + - name: azurefile +{{- if hasPrefix "/" .Values.image.azurefile.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" +{{- else }} + image: "{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" +{{- end }} + args: + - "--v={{ .Values.node.logLevel }}" + - "--endpoint=$(CSI_ENDPOINT)" + - "--nodeid=$(KUBE_NODE_NAME)" + - "--metrics-address=0.0.0.0:{{ .Values.node.metricsPort }}" + - "--kubeconfig={{ .Values.windows.kubeconfig }}" + - "--drivername={{ .Values.driver.name }}" + - "--cloud-config-secret-name={{ .Values.node.cloudConfigSecretName }}" + - "--cloud-config-secret-namespace={{ .Values.node.cloudConfigSecretNamespace }}" + - "--custom-user-agent={{ .Values.driver.customUserAgent }}" + - "--user-agent-suffix={{ .Values.driver.userAgentSuffix }}" + - "--allow-empty-cloud-config={{ .Values.node.allowEmptyCloudConfig }}" + - "--enable-get-volume-stats={{ .Values.feature.enableGetVolumeStats }}" + - "--allow-inline-volume-key-access-with-identity={{ .Values.node.allowInlineVolumeKeyAccessWithIdentity }}" + ports: + - containerPort: {{ .Values.node.livenessProbe.healthPort }} + name: healthz + protocol: TCP + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + timeoutSeconds: 10 + periodSeconds: 30 + env: + - name: AZURE_CREDENTIAL_FILE + valueFrom: + configMapKeyRef: + name: azure-cred-file + key: path-windows + optional: true + - name: CSI_ENDPOINT + value: unix://C:\\csi\\csi.sock + {{- if ne .Values.driver.httpsProxy "" }} + - name: HTTPS_PROXY + value: {{ .Values.driver.httpsProxy }} + {{- end }} + {{- if ne .Values.driver.httpProxy "" }} + - name: HTTP_PROXY + value: {{ .Values.driver.httpProxy }} + {{- end }} + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: AZURE_GO_SDK_LOG_LEVEL + value: {{ .Values.driver.azureGoSDKLogLevel }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + volumeMounts: + - name: kubelet-dir + mountPath: "C:\\var\\lib\\kubelet" + - name: plugin-dir + mountPath: C:\csi + - name: azure-config + mountPath: C:\k + - name: csi-proxy-fs-pipe-v1 + mountPath: \\.\pipe\csi-proxy-filesystem-v1 + - name: csi-proxy-smb-pipe-v1 + mountPath: \\.\pipe\csi-proxy-smb-v1 + # these paths are still included for compatibility, they're used + # only if the node has still the beta version of the CSI proxy + - name: csi-proxy-fs-pipe-v1beta1 + mountPath: \\.\pipe\csi-proxy-filesystem-v1beta1 + - name: csi-proxy-smb-pipe-v1beta1 + mountPath: \\.\pipe\csi-proxy-smb-v1beta1 + resources: {{- toYaml .Values.windows.resources.azurefile | nindent 12 }} + volumes: + - name: csi-proxy-fs-pipe-v1 + hostPath: + path: \\.\pipe\csi-proxy-filesystem-v1 + - name: csi-proxy-smb-pipe-v1 + hostPath: + path: \\.\pipe\csi-proxy-smb-v1 + # these paths are still included for compatibility, they're used + # only if the node has still the beta version of the CSI proxy + - name: csi-proxy-fs-pipe-v1beta1 + hostPath: + path: \\.\pipe\csi-proxy-filesystem-v1beta1 + - name: csi-proxy-smb-pipe-v1beta1 + hostPath: + path: \\.\pipe\csi-proxy-smb-v1beta1 + - name: registration-dir + hostPath: + path: {{ .Values.windows.kubelet }}\plugins_registry\ + type: Directory + - name: kubelet-dir + hostPath: + path: {{ .Values.windows.kubelet }}\ + type: Directory + - name: plugin-dir + hostPath: + path: {{ .Values.windows.kubelet }}\plugins\{{ .Values.driver.name }}\ + type: DirectoryOrCreate + - name: azure-config + hostPath: + path: C:\k + type: Directory +{{- end -}} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node.yaml new file mode 100644 index 0000000000..60a746eb5d --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node.yaml @@ -0,0 +1,217 @@ +{{- if .Values.linux.enabled}} +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: {{ .Values.linux.dsName }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Values.linux.dsName }} + {{- include "azurefile.labels" . | nindent 4 }} +{{- with .Values.linux.labels }} +{{ . | toYaml | indent 4 }} +{{- end }} +{{- with .Values.linux.annotations }} + annotations: +{{ . | toYaml | indent 4 }} +{{- end }} +spec: + updateStrategy: + rollingUpdate: + maxUnavailable: {{ .Values.node.maxUnavailable }} + type: RollingUpdate + selector: + matchLabels: + app: {{ .Values.linux.dsName }} + {{- include "azurefile.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + app: {{ .Values.linux.dsName }} + {{- include "azurefile.labels" . | nindent 8 }} +{{- with .Values.linux.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.linux.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + spec: + hostNetwork: true + dnsPolicy: {{ .Values.linux.dnsPolicy }} + serviceAccountName: {{ .Values.serviceAccount.node }} + nodeSelector: + kubernetes.io/os: linux +{{- with .Values.linux.nodeSelector }} +{{ toYaml . | indent 8 }} +{{- end }} + affinity: +{{- with .Values.linux.affinity }} +{{ toYaml . | indent 8 }} +{{- end }} + nodeAffinity: +{{ toYaml .Values.linux.nodeAffinity | indent 10 }} + priorityClassName: system-node-critical +{{- with .Values.linux.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} +{{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + containers: + - name: liveness-probe + volumeMounts: + - mountPath: /csi + name: socket-dir +{{- if hasPrefix "/" .Values.image.livenessProbe.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- else }} + image: "{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- end }} + args: + - --csi-address=/csi/csi.sock + - --probe-timeout=3s + - --health-port={{ .Values.node.livenessProbe.healthPort }} + - --v=2 + imagePullPolicy: {{ .Values.image.livenessProbe.pullPolicy }} + resources: {{- toYaml .Values.linux.resources.livenessProbe | nindent 12 }} + - name: node-driver-registrar +{{- if hasPrefix "/" .Values.image.nodeDriverRegistrar.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.nodeDriverRegistrar.repository }}:{{ .Values.image.nodeDriverRegistrar.tag }}" +{{- else }} + image: "{{ .Values.image.nodeDriverRegistrar.repository }}:{{ .Values.image.nodeDriverRegistrar.tag }}" +{{- end }} + args: + - --csi-address=$(ADDRESS) + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --v=2 + livenessProbe: + exec: + command: + - /csi-node-driver-registrar + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --mode=kubelet-registration-probe + initialDelaySeconds: 30 + timeoutSeconds: 15 + env: + - name: ADDRESS + value: /csi/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: {{ .Values.linux.kubelet }}/plugins/{{ .Values.driver.name }}/csi.sock + imagePullPolicy: {{ .Values.image.nodeDriverRegistrar.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: registration-dir + mountPath: /registration + resources: {{- toYaml .Values.linux.resources.nodeDriverRegistrar | nindent 12 }} + - name: azurefile +{{- if hasPrefix "/" .Values.image.azurefile.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" +{{- else }} + image: "{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" +{{- end }} + args: + - "--v={{ .Values.node.logLevel }}" + - "--endpoint=$(CSI_ENDPOINT)" + - "--nodeid=$(KUBE_NODE_NAME)" + - "--metrics-address=0.0.0.0:{{ .Values.node.metricsPort }}" + - "--kubeconfig={{ .Values.linux.kubeconfig }}" + - "--drivername={{ .Values.driver.name }}" + - "--cloud-config-secret-name={{ .Values.node.cloudConfigSecretName }}" + - "--cloud-config-secret-namespace={{ .Values.node.cloudConfigSecretNamespace }}" + - "--custom-user-agent={{ .Values.driver.customUserAgent }}" + - "--user-agent-suffix={{ .Values.driver.userAgentSuffix }}" + - "--allow-empty-cloud-config={{ .Values.node.allowEmptyCloudConfig }}" + - "--enable-get-volume-stats={{ .Values.feature.enableGetVolumeStats }}" + - "--mount-permissions={{ .Values.linux.mountPermissions }}" + - "--allow-inline-volume-key-access-with-identity={{ .Values.node.allowInlineVolumeKeyAccessWithIdentity }}" + ports: + - containerPort: {{ .Values.node.livenessProbe.healthPort }} + name: healthz + protocol: TCP + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + timeoutSeconds: 10 + periodSeconds: 30 + env: + - name: AZURE_CREDENTIAL_FILE + valueFrom: + configMapKeyRef: + name: azure-cred-file + key: path + optional: true + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + {{- if ne .Values.driver.httpsProxy "" }} + - name: HTTPS_PROXY + value: {{ .Values.driver.httpsProxy }} + {{- end }} + {{- if ne .Values.driver.httpProxy "" }} + - name: HTTP_PROXY + value: {{ .Values.driver.httpProxy }} + {{- end }} + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: AZURE_GO_SDK_LOG_LEVEL + value: {{ .Values.driver.azureGoSDKLogLevel }} + imagePullPolicy: {{ .Values.image.azurefile.pullPolicy }} + securityContext: + privileged: true + volumeMounts: + - mountPath: /csi + name: socket-dir + - mountPath: {{ .Values.linux.kubelet }}/ + mountPropagation: Bidirectional + name: mountpoint-dir + - mountPath: /etc/kubernetes/ + name: azure-cred + - mountPath: /dev + name: device-dir + {{- if eq .Values.linux.distro "fedora" }} + - name: ssl + mountPath: /etc/ssl/certs + readOnly: true + - name: ssl-pki + mountPath: /etc/pki/ca-trust/extracted + readOnly: true + {{- end }} + resources: {{- toYaml .Values.linux.resources.azurefile | nindent 12 }} + volumes: + - hostPath: + path: {{ .Values.linux.kubelet }}/plugins/{{ .Values.driver.name }} + type: DirectoryOrCreate + name: socket-dir + - hostPath: + path: {{ .Values.linux.kubelet }}/ + type: DirectoryOrCreate + name: mountpoint-dir + - hostPath: + path: {{ .Values.linux.kubelet }}/plugins_registry/ + type: DirectoryOrCreate + name: registration-dir + - hostPath: + path: /etc/kubernetes/ + type: DirectoryOrCreate + name: azure-cred + - hostPath: + path: /dev + type: Directory + name: device-dir + {{- if eq .Values.linux.distro "fedora" }} + - name: ssl + hostPath: + path: /etc/ssl/certs + - name: ssl-pki + hostPath: + path: /etc/pki/ca-trust/extracted + {{- end }} +{{- end -}} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/csi-snapshot-controller.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/csi-snapshot-controller.yaml new file mode 100644 index 0000000000..b1f7eff92c --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/templates/csi-snapshot-controller.yaml @@ -0,0 +1,65 @@ +{{- if .Values.snapshot.enabled -}} +kind: Deployment +apiVersion: apps/v1 +metadata: + name: {{ .Values.snapshot.snapshotController.name}} + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Values.snapshot.snapshotController.name}} + {{- include "azurefile.labels" . | nindent 4 }} +{{- with .Values.snapshot.snapshotController.labels }} +{{ . | toYaml | indent 4 }} +{{- end }} +{{- with .Values.snapshot.snapshotController.annotations }} + annotations: +{{ . | toYaml | indent 4 }} +{{- end }} +spec: + replicas: {{ .Values.snapshot.snapshotController.replicas }} + selector: + matchLabels: + app: {{ .Values.snapshot.snapshotController.name}} + {{- include "azurefile.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + app: {{ .Values.snapshot.snapshotController.name}} + {{- include "azurefile.labels" . | nindent 8 }} +{{- with .Values.snapshot.snapshotController.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.snapshot.snapshotController.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + spec: + serviceAccountName: {{ .Values.serviceAccount.snapshotController }} + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical +{{- with .Values.controller.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.controller.affinity }} + affinity: +{{ toYaml . | indent 8 }} +{{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + containers: + - name: {{ .Values.snapshot.snapshotController.name}} +{{- if hasPrefix "/" .Values.snapshot.image.csiSnapshotController.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.snapshot.image.csiSnapshotController.repository }}:{{ .Values.snapshot.image.csiSnapshotController.tag }}" +{{- else }} + image: "{{ .Values.snapshot.image.csiSnapshotController.repository }}:{{ .Values.snapshot.image.csiSnapshotController.tag }}" +{{- end }} + args: + - "--v=2" + - "--leader-election=true" + - "--leader-election-namespace={{ .Release.Namespace }}" + resources: {{- toYaml .Values.snapshot.snapshotController.resources | nindent 12 }} + imagePullPolicy: {{ .Values.snapshot.image.csiSnapshotController.pullPolicy }} +{{- end -}} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml new file mode 100644 index 0000000000..09923c06a5 --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml @@ -0,0 +1,207 @@ +{{- if .Values.rbac.create -}} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-external-provisioner-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +rules: + - 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: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["get", "list"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-csi-provisioner-binding + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.controller }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Values.rbac.name }}-external-provisioner-role + apiGroup: rbac.authorization.k8s.io + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-external-attacher-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +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", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-csi-attacher-binding + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.controller }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Values.rbac.name }}-external-attacher-role + apiGroup: rbac.authorization.k8s.io + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-external-snapshotter-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-csi-snapshotter-binding + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.controller }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Values.rbac.name }}-external-snapshotter-role + apiGroup: rbac.authorization.k8s.io + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-external-resizer-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.rbac.name }}-csi-resizer-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.controller }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Values.rbac.name }}-external-resizer-role + apiGroup: rbac.authorization.k8s.io + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-{{ .Values.rbac.name }}-controller-secret-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "create"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-{{ .Values.rbac.name }}-controller-secret-binding + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.controller }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-{{ .Values.rbac.name }}-controller-secret-role + apiGroup: rbac.authorization.k8s.io +{{ end }} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml new file mode 100644 index 0000000000..4e1fbcde94 --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml @@ -0,0 +1,29 @@ +{{- if .Values.rbac.create -}} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-{{ .Values.rbac.name }}-node-secret-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-{{ .Values.rbac.name }}-node-secret-binding + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.node }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-{{ .Values.rbac.name }}-node-secret-role + apiGroup: rbac.authorization.k8s.io +{{ end }} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml new file mode 100644 index 0000000000..0cff1ff01f --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml @@ -0,0 +1,80 @@ +{{- if and .Values.snapshot.enabled .Values.rbac.create -}} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch"] + - 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: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update", "patch"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-binding + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.snapshotController }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-snapshot-controller-role + apiGroup: rbac.authorization.k8s.io + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-leaderelection-role + labels: + {{- include "azurefile.labels" . | nindent 4 }} +rules: + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-leaderelection-binding + labels: + {{- include "azurefile.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.snapshotController }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: csi-snapshot-controller-leaderelection-role + apiGroup: rbac.authorization.k8s.io +{{ end }} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml new file mode 100644 index 0000000000..66e0726acb --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml @@ -0,0 +1,9 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.controller }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "azurefile.labels" . | nindent 4 }} +{{- end -}} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml new file mode 100644 index 0000000000..697b8db390 --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml @@ -0,0 +1,9 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.node }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "azurefile.labels" . | nindent 4 }} +{{- end -}} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml new file mode 100644 index 0000000000..e77ef8f991 --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml @@ -0,0 +1,9 @@ +{{- if and .Values.snapshot.enabled .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.snapshotController }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "azurefile.labels" . | nindent 4 }} +{{- end -}} diff --git a/charts/v1.26.1/azurefile-csi-driver/values.yaml b/charts/v1.26.1/azurefile-csi-driver/values.yaml new file mode 100644 index 0000000000..f290d24ee6 --- /dev/null +++ b/charts/v1.26.1/azurefile-csi-driver/values.yaml @@ -0,0 +1,254 @@ +image: + baseRepo: mcr.microsoft.com + azurefile: + repository: /oss/kubernetes-csi/azurefile-csi + tag: v1.26.1 + pullPolicy: IfNotPresent + csiProvisioner: + repository: /oss/kubernetes-csi/csi-provisioner + tag: v3.3.0 + pullPolicy: IfNotPresent + csiAttacher: + repository: /oss/kubernetes-csi/csi-attacher + tag: v4.0.0 + pullPolicy: IfNotPresent + csiResizer: + repository: /oss/kubernetes-csi/csi-resizer + tag: v1.6.0 + pullPolicy: IfNotPresent + livenessProbe: + repository: /oss/kubernetes-csi/livenessprobe + tag: v2.8.0 + pullPolicy: IfNotPresent + nodeDriverRegistrar: + repository: /oss/kubernetes-csi/csi-node-driver-registrar + tag: v2.6.2 + pullPolicy: IfNotPresent + +## Reference to one or more secrets to be used when pulling images +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] +# - name: myRegistryKeySecretName + +# -- Custom labels to add into metadata +customLabels: {} + # k8s-app: azurefile-csi-driver + +serviceAccount: + create: true # When true, service accounts will be created for you. Set to false if you want to use your own. + controller: csi-azurefile-controller-sa # Name of Service Account to be created or used + node: csi-azurefile-node-sa # Name of Service Account to be created or used + snapshotController: csi-snapshot-controller-sa # Name of Service Account to be created or used + +rbac: + create: true + name: azurefile + +controller: + name: csi-azurefile-controller + cloudConfigSecretName: azure-cloud-provider + cloudConfigSecretNamespace: kube-system + allowEmptyCloudConfig: true + replicas: 2 + hostNetwork: true # this setting could be disabled if controller does not depend on MSI setting + metricsPort: 29614 + livenessProbe: + healthPort: 29612 + runOnMaster: false + runOnControlPlane: false + attachRequired: false + logLevel: 5 + labels: {} + annotations: {} + podLabels: {} + podAnnotations: {} + resources: + csiProvisioner: + limits: + cpu: 1 + memory: 500Mi + requests: + cpu: 10m + memory: 20Mi + csiAttacher: + limits: + cpu: 1 + memory: 500Mi + requests: + cpu: 10m + memory: 20Mi + csiResizer: + limits: + cpu: 1 + memory: 500Mi + requests: + cpu: 10m + memory: 20Mi + csiSnapshotter: + limits: + cpu: 1 + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + livenessProbe: + limits: + cpu: 1 + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + azurefile: + limits: + cpu: 1 + memory: 200Mi + requests: + cpu: 10m + memory: 20Mi + kubeconfig: "" + affinity: {} + nodeSelector: {} + tolerations: + - key: "node-role.kubernetes.io/master" + operator: "Exists" + effect: "NoSchedule" + - key: "node-role.kubernetes.io/controlplane" + operator: "Exists" + effect: "NoSchedule" + - key: "node-role.kubernetes.io/control-plane" + operator: "Exists" + effect: "NoSchedule" + +node: + cloudConfigSecretName: azure-cloud-provider + cloudConfigSecretNamespace: kube-system + allowEmptyCloudConfig: true + allowInlineVolumeKeyAccessWithIdentity: false + metricsPort: 29615 + livenessProbe: + healthPort: 29613 + logLevel: 5 + +snapshot: + enabled: false + image: + csiSnapshotter: + repository: /oss/kubernetes-csi/csi-snapshotter + tag: v5.0.1 + pullPolicy: IfNotPresent + csiSnapshotController: + repository: /oss/kubernetes-csi/snapshot-controller + tag: v5.0.1 + pullPolicy: IfNotPresent + snapshotController: + name: csi-snapshot-controller + replicas: 2 + labels: {} + annotations: {} + podLabels: {} + podAnnotations: {} + resources: + limits: + cpu: 1 + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + +feature: + enableGetVolumeStats: true + +driver: + name: file.csi.azure.com + customUserAgent: "" + userAgentSuffix: "OSS-helm" + azureGoSDKLogLevel: "" # available values: ""(no logs), DEBUG, INFO, WARNING, ERROR + httpsProxy: "" + httpProxy: "" + +linux: + enabled: true + dsName: csi-azurefile-node # daemonset name + dnsPolicy: Default # available values: Default, ClusterFirst, ClusterFirstWithHostNet, None + kubelet: /var/lib/kubelet + kubeconfig: "" + distro: debian # available values: debian, fedora + mountPermissions: 0777 + labels: {} + annotations: {} + podLabels: {} + podAnnotations: {} + resources: + livenessProbe: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + nodeDriverRegistrar: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + azurefile: + limits: + memory: 400Mi + requests: + cpu: 10m + memory: 20Mi + tolerations: + - operator: "Exists" + nodeSelector: {} + affinity: {} + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: type + operator: NotIn + values: + - virtual-kubelet + +windows: + enabled: true + dsName: csi-azurefile-node-win # daemonset name + kubelet: 'C:\var\lib\kubelet' + kubeconfig: "" + labels: {} + annotations: {} + podLabels: {} + podAnnotations: {} + resources: + livenessProbe: + limits: + memory: 150Mi + requests: + cpu: 10m + memory: 40Mi + nodeDriverRegistrar: + limits: + memory: 150Mi + requests: + cpu: 30m + memory: 40Mi + azurefile: + limits: + memory: 200Mi + requests: + cpu: 10m + memory: 40Mi + tolerations: + - key: "node.kubernetes.io/os" + operator: "Exists" + effect: "NoSchedule" + nodeSelector: {} + affinity: {} + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: type + operator: NotIn + values: + - virtual-kubelet diff --git a/deploy/csi-azurefile-controller.yaml b/deploy/csi-azurefile-controller.yaml index 623890f3ee..71e8da9221 100644 --- a/deploy/csi-azurefile-controller.yaml +++ b/deploy/csi-azurefile-controller.yaml @@ -133,7 +133,7 @@ spec: cpu: 10m memory: 20Mi - name: azurefile - image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest + image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.1 imagePullPolicy: IfNotPresent args: - "--v=5" diff --git a/deploy/csi-azurefile-driver.yaml b/deploy/csi-azurefile-driver.yaml index 55d31ed2d1..0b4ecbbe26 100644 --- a/deploy/csi-azurefile-driver.yaml +++ b/deploy/csi-azurefile-driver.yaml @@ -4,7 +4,7 @@ kind: CSIDriver metadata: name: file.csi.azure.com annotations: - csiDriver: latest + csiDriver: v1.26.1 snapshot: v5.0.1 spec: attachRequired: false diff --git a/deploy/csi-azurefile-node-windows.yaml b/deploy/csi-azurefile-node-windows.yaml index 9340864653..11d1891cf8 100644 --- a/deploy/csi-azurefile-node-windows.yaml +++ b/deploy/csi-azurefile-node-windows.yaml @@ -91,7 +91,7 @@ spec: cpu: 30m memory: 40Mi - name: azurefile - image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest + image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.1 imagePullPolicy: IfNotPresent args: - --v=5 diff --git a/deploy/csi-azurefile-node.yaml b/deploy/csi-azurefile-node.yaml index f36a6a9545..c7f63edd00 100644 --- a/deploy/csi-azurefile-node.yaml +++ b/deploy/csi-azurefile-node.yaml @@ -82,7 +82,7 @@ spec: cpu: 10m memory: 20Mi - name: azurefile - image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest + image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.1 imagePullPolicy: IfNotPresent args: - "--v=5" diff --git a/deploy/v1.26.1/crd-csi-snapshot.yaml b/deploy/v1.26.1/crd-csi-snapshot.yaml new file mode 100644 index 0000000000..18d97e6b7c --- /dev/null +++ b/deploy/v1.26.1/crd-csi-snapshot.yaml @@ -0,0 +1,659 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + creationTimestamp: null + name: volumesnapshots.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshot + listKind: VolumeSnapshotList + plural: volumesnapshots + shortNames: + - vs + singular: volumesnapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' + properties: + source: + description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. + type: string + type: object + oneOf: + - required: ["persistentVolumeClaimName"] + - required: ["volumeSnapshotContentName"] + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurrs during the snapshot creation. Upon success, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + type: string + description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshot is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshot" + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' + properties: + source: + description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurrs during the snapshot creation. Upon success, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + type: string + description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + creationTimestamp: null + name: volumesnapshotclasses.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotClass + listKind: VolumeSnapshotClassList + plural: volumesnapshotclasses + shortNames: + - vsclass + - vsclasses + singular: volumesnapshotclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotClass is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotClass" + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + creationTimestamp: null + name: volumesnapshotcontents.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotContent + listKind: VolumeSnapshotContentList + plural: volumesnapshotcontents + shortNames: + - vsc + - vscs + singular: volumesnapshotcontent + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. + type: string + type: object + oneOf: + - required: ["snapshotHandle"] + - required: ["volumeHandle"] + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotContent is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotContent" + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. + type: string + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] \ No newline at end of file diff --git a/deploy/v1.26.1/csi-azurefile-controller.yaml b/deploy/v1.26.1/csi-azurefile-controller.yaml new file mode 100644 index 0000000000..71e8da9221 --- /dev/null +++ b/deploy/v1.26.1/csi-azurefile-controller.yaml @@ -0,0 +1,184 @@ +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: csi-azurefile-controller + namespace: kube-system +spec: + replicas: 2 + selector: + matchLabels: + app: csi-azurefile-controller + template: + metadata: + labels: + app: csi-azurefile-controller + spec: + hostNetwork: true # only required for MSI enabled cluster + serviceAccountName: csi-azurefile-controller-sa + nodeSelector: + kubernetes.io/os: linux # add "kubernetes.io/role: master" to run controller on master node + priorityClassName: system-cluster-critical + tolerations: + - key: "node-role.kubernetes.io/master" + operator: "Exists" + effect: "NoSchedule" + - key: "node-role.kubernetes.io/controlplane" + operator: "Exists" + effect: "NoSchedule" + - key: "node-role.kubernetes.io/control-plane" + operator: "Exists" + effect: "NoSchedule" + containers: + - name: csi-provisioner + image: mcr.microsoft.com/oss/kubernetes-csi/csi-provisioner:v3.3.0 + args: + - "-v=2" + - "--csi-address=$(ADDRESS)" + - "--leader-election" + - "--leader-election-namespace=kube-system" + - "--timeout=300s" + - "--extra-create-metadata=true" + - "--kube-api-qps=50" + - "--kube-api-burst=100" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - mountPath: /csi + name: socket-dir + resources: + limits: + memory: 500Mi + requests: + cpu: 10m + memory: 20Mi + - name: csi-attacher + image: mcr.microsoft.com/oss/kubernetes-csi/csi-attacher:v4.0.0 + args: + - "-v=2" + - "-csi-address=$(ADDRESS)" + - "-timeout=120s" + - "--leader-election" + - "--leader-election-namespace=kube-system" + - "--kube-api-qps=50" + - "--kube-api-burst=100" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - mountPath: /csi + name: socket-dir + resources: + limits: + memory: 500Mi + requests: + cpu: 10m + memory: 20Mi + - name: csi-snapshotter + image: mcr.microsoft.com/oss/kubernetes-csi/csi-snapshotter:v5.0.1 + args: + - "-v=2" + - "-csi-address=$(ADDRESS)" + - "--leader-election" + - "--leader-election-namespace=kube-system" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /csi + resources: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + - name: csi-resizer + image: mcr.microsoft.com/oss/kubernetes-csi/csi-resizer:v1.6.0 + args: + - "-csi-address=$(ADDRESS)" + - "-v=2" + - "--leader-election" + - "--leader-election-namespace=kube-system" + - '-handle-volume-inuse-error=false' + - '-feature-gates=RecoverVolumeExpansionFailure=true' + - '-timeout=120s' + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /csi + resources: + limits: + memory: 500Mi + requests: + cpu: 10m + memory: 20Mi + - name: liveness-probe + image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.8.0 + args: + - --csi-address=/csi/csi.sock + - --probe-timeout=3s + - --health-port=29612 + - --v=2 + volumeMounts: + - name: socket-dir + mountPath: /csi + resources: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + - name: azurefile + image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.1 + imagePullPolicy: IfNotPresent + args: + - "--v=5" + - "--endpoint=$(CSI_ENDPOINT)" + - "--metrics-address=0.0.0.0:29614" + - "--user-agent-suffix=OSS-kubectl" + ports: + - containerPort: 29612 + name: healthz + protocol: TCP + - containerPort: 29614 + name: metrics + protocol: TCP + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + timeoutSeconds: 10 + periodSeconds: 30 + env: + - name: AZURE_CREDENTIAL_FILE + valueFrom: + configMapKeyRef: + name: azure-cred-file + key: path + optional: true + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + volumeMounts: + - mountPath: /csi + name: socket-dir + - mountPath: /etc/kubernetes/ + name: azure-cred + resources: + limits: + memory: 200Mi + requests: + cpu: 10m + memory: 20Mi + volumes: + - name: socket-dir + emptyDir: {} + - name: azure-cred + hostPath: + path: /etc/kubernetes/ + type: DirectoryOrCreate diff --git a/deploy/v1.26.1/csi-azurefile-driver.yaml b/deploy/v1.26.1/csi-azurefile-driver.yaml new file mode 100644 index 0000000000..0b4ecbbe26 --- /dev/null +++ b/deploy/v1.26.1/csi-azurefile-driver.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: file.csi.azure.com + annotations: + csiDriver: v1.26.1 + snapshot: v5.0.1 +spec: + attachRequired: false + podInfoOnMount: true + volumeLifecycleModes: + - Persistent + - Ephemeral + fsGroupPolicy: ReadWriteOnceWithFSType diff --git a/deploy/v1.26.1/csi-azurefile-node-windows.yaml b/deploy/v1.26.1/csi-azurefile-node-windows.yaml new file mode 100644 index 0000000000..11d1891cf8 --- /dev/null +++ b/deploy/v1.26.1/csi-azurefile-node-windows.yaml @@ -0,0 +1,181 @@ +--- +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: csi-azurefile-node-win + namespace: kube-system +spec: + updateStrategy: + rollingUpdate: + maxUnavailable: 1 + type: RollingUpdate + selector: + matchLabels: + app: csi-azurefile-node-win + template: + metadata: + labels: + app: csi-azurefile-node-win + spec: + serviceAccountName: csi-azurefile-node-sa + tolerations: + - key: "node.kubernetes.io/os" + operator: "Exists" + effect: "NoSchedule" + nodeSelector: + kubernetes.io/os: windows + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: type + operator: NotIn + values: + - virtual-kubelet + priorityClassName: system-node-critical + containers: + - name: liveness-probe + volumeMounts: + - mountPath: C:\csi + name: plugin-dir + image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.8.0 + args: + - --csi-address=$(CSI_ENDPOINT) + - --probe-timeout=3s + - --health-port=29613 + - --v=2 + env: + - name: CSI_ENDPOINT + value: unix://C:\\csi\\csi.sock + resources: + limits: + memory: 150Mi + requests: + cpu: 10m + memory: 40Mi + - name: node-driver-registrar + image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.6.2 + args: + - --v=2 + - --csi-address=$(CSI_ENDPOINT) + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + livenessProbe: + exec: + command: + - /csi-node-driver-registrar.exe + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --mode=kubelet-registration-probe + initialDelaySeconds: 60 + timeoutSeconds: 30 + env: + - name: CSI_ENDPOINT + value: unix://C:\\csi\\csi.sock + - name: DRIVER_REG_SOCK_PATH + value: C:\\var\\lib\\kubelet\\plugins\\file.csi.azure.com\\csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + volumeMounts: + - name: kubelet-dir + mountPath: "C:\\var\\lib\\kubelet" + - name: plugin-dir + mountPath: C:\csi + - name: registration-dir + mountPath: C:\registration + resources: + limits: + memory: 150Mi + requests: + cpu: 30m + memory: 40Mi + - name: azurefile + image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.1 + imagePullPolicy: IfNotPresent + args: + - --v=5 + - --endpoint=$(CSI_ENDPOINT) + - --nodeid=$(KUBE_NODE_NAME) + - --kubeconfig=C:\\k\\config + - --metrics-address=0.0.0.0:29615 + ports: + - containerPort: 29613 + name: healthz + protocol: TCP + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + timeoutSeconds: 10 + periodSeconds: 30 + env: + - name: AZURE_CREDENTIAL_FILE + valueFrom: + configMapKeyRef: + name: azure-cred-file + key: path-windows + optional: true + - name: CSI_ENDPOINT + value: unix://C:\\csi\\csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + volumeMounts: + - name: kubelet-dir + mountPath: "C:\\var\\lib\\kubelet" + - name: plugin-dir + mountPath: C:\csi + - name: azure-config + mountPath: C:\k + - name: csi-proxy-fs-pipe-v1 + mountPath: \\.\pipe\csi-proxy-filesystem-v1 + - name: csi-proxy-smb-pipe-v1 + mountPath: \\.\pipe\csi-proxy-smb-v1 + # these paths are still included for compatibility, they're used + # only if the node has still the beta version of the CSI proxy + - name: csi-proxy-fs-pipe-v1beta1 + mountPath: \\.\pipe\csi-proxy-filesystem-v1beta1 + - name: csi-proxy-smb-pipe-v1beta1 + mountPath: \\.\pipe\csi-proxy-smb-v1beta1 + resources: + limits: + memory: 200Mi + requests: + cpu: 10m + memory: 40Mi + volumes: + - name: csi-proxy-fs-pipe-v1 + hostPath: + path: \\.\pipe\csi-proxy-filesystem-v1 + - name: csi-proxy-smb-pipe-v1 + hostPath: + path: \\.\pipe\csi-proxy-smb-v1 + # these paths are still included for compatibility, they're used + # only if the node has still the beta version of the CSI proxy + - name: csi-proxy-fs-pipe-v1beta1 + hostPath: + path: \\.\pipe\csi-proxy-filesystem-v1beta1 + - name: csi-proxy-smb-pipe-v1beta1 + hostPath: + path: \\.\pipe\csi-proxy-smb-v1beta1 + - name: registration-dir + hostPath: + path: C:\var\lib\kubelet\plugins_registry\ + type: Directory + - name: kubelet-dir + hostPath: + path: C:\var\lib\kubelet\ + type: Directory + - name: plugin-dir + hostPath: + path: C:\var\lib\kubelet\plugins\file.csi.azure.com\ + type: DirectoryOrCreate + - name: azure-config + hostPath: + path: C:\k + type: DirectoryOrCreate diff --git a/deploy/v1.26.1/csi-azurefile-node.yaml b/deploy/v1.26.1/csi-azurefile-node.yaml new file mode 100644 index 0000000000..c7f63edd00 --- /dev/null +++ b/deploy/v1.26.1/csi-azurefile-node.yaml @@ -0,0 +1,157 @@ +--- +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: csi-azurefile-node + namespace: kube-system +spec: + updateStrategy: + rollingUpdate: + maxUnavailable: 1 + type: RollingUpdate + selector: + matchLabels: + app: csi-azurefile-node + template: + metadata: + labels: + app: csi-azurefile-node + spec: + hostNetwork: true + dnsPolicy: Default + serviceAccountName: csi-azurefile-node-sa + nodeSelector: + kubernetes.io/os: linux + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: type + operator: NotIn + values: + - virtual-kubelet + priorityClassName: system-node-critical + tolerations: + - operator: "Exists" + containers: + - name: liveness-probe + volumeMounts: + - mountPath: /csi + name: socket-dir + image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.8.0 + args: + - --csi-address=/csi/csi.sock + - --probe-timeout=3s + - --health-port=29613 + - --v=2 + resources: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + - name: node-driver-registrar + image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.6.2 + args: + - --csi-address=$(ADDRESS) + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --v=2 + livenessProbe: + exec: + command: + - /csi-node-driver-registrar + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --mode=kubelet-registration-probe + initialDelaySeconds: 30 + timeoutSeconds: 15 + env: + - name: ADDRESS + value: /csi/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: /var/lib/kubelet/plugins/file.csi.azure.com/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: registration-dir + mountPath: /registration + resources: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi + - name: azurefile + image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.1 + imagePullPolicy: IfNotPresent + args: + - "--v=5" + - "--endpoint=$(CSI_ENDPOINT)" + - "--nodeid=$(KUBE_NODE_NAME)" + - "--metrics-address=0.0.0.0:29615" + ports: + - containerPort: 29613 + name: healthz + protocol: TCP + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + timeoutSeconds: 10 + periodSeconds: 30 + env: + - name: AZURE_CREDENTIAL_FILE + valueFrom: + configMapKeyRef: + name: azure-cred-file + key: path + optional: true + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + securityContext: + privileged: true + volumeMounts: + - mountPath: /csi + name: socket-dir + - mountPath: /var/lib/kubelet/ + mountPropagation: Bidirectional + name: mountpoint-dir + - mountPath: /etc/kubernetes/ + name: azure-cred + - mountPath: /dev + name: device-dir + resources: + limits: + memory: 400Mi + requests: + cpu: 10m + memory: 20Mi + volumes: + - hostPath: + path: /var/lib/kubelet/plugins/file.csi.azure.com + type: DirectoryOrCreate + name: socket-dir + - hostPath: + path: /var/lib/kubelet/ + type: DirectoryOrCreate + name: mountpoint-dir + - hostPath: + path: /var/lib/kubelet/plugins_registry/ + type: DirectoryOrCreate + name: registration-dir + - hostPath: + path: /etc/kubernetes/ + type: DirectoryOrCreate + name: azure-cred + - hostPath: + path: /dev + type: Directory + name: device-dir +--- diff --git a/deploy/v1.26.1/csi-snapshot-controller.yaml b/deploy/v1.26.1/csi-snapshot-controller.yaml new file mode 100644 index 0000000000..79c7483bb5 --- /dev/null +++ b/deploy/v1.26.1/csi-snapshot-controller.yaml @@ -0,0 +1,46 @@ +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: csi-snapshot-controller + namespace: kube-system +spec: + replicas: 2 + selector: + matchLabels: + app: csi-snapshot-controller + template: + metadata: + labels: + app: csi-snapshot-controller + spec: + serviceAccountName: csi-snapshot-controller-sa + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + tolerations: + - key: "node-role.kubernetes.io/master" + operator: "Equal" + value: "true" + effect: "NoSchedule" + - key: "node-role.kubernetes.io/controlplane" + operator: "Equal" + value: "true" + effect: "NoSchedule" + - key: "node-role.kubernetes.io/control-plane" + operator: "Equal" + value: "true" + effect: "NoSchedule" + containers: + - name: csi-snapshot-controller + image: mcr.microsoft.com/oss/kubernetes-csi/snapshot-controller:v5.0.1 + args: + - "--v=2" + - "--leader-election=true" + - "--leader-election-namespace=kube-system" + resources: + limits: + memory: 100Mi + requests: + cpu: 10m + memory: 20Mi diff --git a/deploy/v1.26.1/rbac-csi-azurefile-controller.yaml b/deploy/v1.26.1/rbac-csi-azurefile-controller.yaml new file mode 100644 index 0000000000..b9348c8cd5 --- /dev/null +++ b/deploy/v1.26.1/rbac-csi-azurefile-controller.yaml @@ -0,0 +1,194 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-azurefile-controller-sa + namespace: kube-system + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-external-provisioner-role +rules: + - 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: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["get", "list"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-csi-provisioner-binding +subjects: + - kind: ServiceAccount + name: csi-azurefile-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: azurefile-external-provisioner-role + apiGroup: rbac.authorization.k8s.io + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-external-attacher-role +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", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-csi-attacher-binding +subjects: + - kind: ServiceAccount + name: csi-azurefile-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: azurefile-external-attacher-role + apiGroup: rbac.authorization.k8s.io + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-external-snapshotter-role +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-csi-snapshotter-binding +subjects: + - kind: ServiceAccount + name: csi-azurefile-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: azurefile-external-snapshotter-role + apiGroup: rbac.authorization.k8s.io + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-external-resizer-role +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: azurefile-csi-resizer-role +subjects: + - kind: ServiceAccount + name: csi-azurefile-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: azurefile-external-resizer-role + apiGroup: rbac.authorization.k8s.io + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-azurefile-controller-secret-role +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "create"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-azurefile-controller-secret-binding +subjects: + - kind: ServiceAccount + name: csi-azurefile-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: csi-azurefile-controller-secret-role + apiGroup: rbac.authorization.k8s.io diff --git a/deploy/v1.26.1/rbac-csi-azurefile-node.yaml b/deploy/v1.26.1/rbac-csi-azurefile-node.yaml new file mode 100644 index 0000000000..3752f36aa4 --- /dev/null +++ b/deploy/v1.26.1/rbac-csi-azurefile-node.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-azurefile-node-sa + namespace: kube-system + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-azurefile-node-secret-role +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-azurefile-node-secret-binding +subjects: + - kind: ServiceAccount + name: csi-azurefile-node-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: csi-azurefile-node-secret-role + apiGroup: rbac.authorization.k8s.io diff --git a/deploy/v1.26.1/rbac-csi-snapshot-controller.yaml b/deploy/v1.26.1/rbac-csi-snapshot-controller.yaml new file mode 100644 index 0000000000..03af765424 --- /dev/null +++ b/deploy/v1.26.1/rbac-csi-snapshot-controller.yaml @@ -0,0 +1,78 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-snapshot-controller-sa + namespace: kube-system + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-role +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch"] + - 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: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update", "patch"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-binding +subjects: + - kind: ServiceAccount + name: csi-snapshot-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: csi-snapshot-controller-role + apiGroup: rbac.authorization.k8s.io + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-leaderelection-role +rules: + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshot-controller-leaderelection-binding +subjects: + - kind: ServiceAccount + name: csi-snapshot-controller-sa + namespace: kube-system +roleRef: + kind: ClusterRole + name: csi-snapshot-controller-leaderelection-role + apiGroup: rbac.authorization.k8s.io diff --git a/docs/install-azurefile-csi-driver.md b/docs/install-azurefile-csi-driver.md index 83c0c73f7d..2c03a5a943 100644 --- a/docs/install-azurefile-csi-driver.md +++ b/docs/install-azurefile-csi-driver.md @@ -4,6 +4,6 @@ > - please use helm install method for more customization, e.g. Azure Stack, RedHat OpenShift support. - [install CSI driver master version](./install-csi-driver-master.md)(only for testing purpose) - - [install v1.26.0 CSI driver](./install-csi-driver-v1.26.0.md) + - [install v1.26.1 CSI driver](./install-csi-driver-v1.26.1.md) - [install v1.25.1 CSI driver](./install-csi-driver-v1.25.1.md) - [install v1.24.0 CSI driver](./install-csi-driver-v1.24.0.md) diff --git a/docs/install-csi-driver-v1.26.1.md b/docs/install-csi-driver-v1.26.1.md new file mode 100644 index 0000000000..9d25aab0d6 --- /dev/null +++ b/docs/install-csi-driver-v1.26.1.md @@ -0,0 +1,45 @@ +## Install azurefile CSI driver v1.26.1 version on a Kubernetes cluster +If you have already installed Helm, you can also use it to install this driver. Please check [Installation with Helm](../charts/README.md). + +### Install by kubectl + - Option#1. remote install +```console +curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/v1.26.1/deploy/install-driver.sh | bash -s v1.26.1 -- +``` + + - Option#2. local install +```console +git clone https://github.com/kubernetes-sigs/azurefile-csi-driver.git +cd azurefile-csi-driver +git checkout v1.26.1 +./deploy/install-driver.sh v1.26.1 local +``` + + - check pods status: +```console +kubectl -n kube-system get pod -o wide --watch -l app=csi-azurefile-controller +kubectl -n kube-system get pod -o wide --watch -l app=csi-azurefile-node +``` + +example output: + +``` +NAME READY STATUS RESTARTS AGE IP NODE +csi-azurefile-controller-56bfddd689-dh5tk 6/6 Running 0 35s 10.240.0.19 k8s-agentpool-22533604-0 +csi-azurefile-node-cvgbs 3/3 Running 0 7m4s 10.240.0.35 k8s-agentpool-22533604-1 +csi-azurefile-node-dr4s4 3/3 Running 0 7m4s 10.240.0.4 k8s-agentpool-22533604-0 +``` + +### clean up CSI driver + - Option#1. remote uninstall +```console +curl -skSL https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/v1.26.1/deploy/uninstall-driver.sh | bash -s -- +``` + + - Option#2. local uninstall +```console +git clone https://github.com/kubernetes-sigs/azurefile-csi-driver.git +cd azurefile-csi-driver +git checkout v1.26.1 +./deploy/install-driver.sh v1.26.1 local +``` From 0498528edfaf395d0ca69fdffe8d864443da2e18 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Thu, 16 Feb 2023 08:01:57 +0000 Subject: [PATCH 024/109] doc: use latest version for master branch --- charts/index.yaml | 78 +++++++++--------- charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 0 -> 11434 bytes .../latest/azurefile-csi-driver-v1.26.1.tgz | Bin 11419 -> 0 bytes charts/latest/azurefile-csi-driver/Chart.yaml | 4 +- .../latest/azurefile-csi-driver/values.yaml | 4 +- deploy/csi-azurefile-controller.yaml | 2 +- deploy/csi-azurefile-driver.yaml | 2 +- deploy/csi-azurefile-node-windows.yaml | 2 +- deploy/csi-azurefile-node.yaml | 2 +- 9 files changed, 47 insertions(+), 47 deletions(-) create mode 100644 charts/latest/azurefile-csi-driver-v0.0.0.tgz delete mode 100644 charts/latest/azurefile-csi-driver-v1.26.1.tgz diff --git a/charts/index.yaml b/charts/index.yaml index 6876525a8d..0699e864e4 100644 --- a/charts/index.yaml +++ b/charts/index.yaml @@ -3,16 +3,7 @@ entries: azurefile-csi-driver: - apiVersion: v1 appVersion: v1.26.1 - created: "2023-02-16T07:31:47.255463147Z" - description: Azure File Container Storage Interface (CSI) Storage Plugin - digest: c7bf2a1b9c03c4281b038c5341489b63a98d0353be4fa3518df0c4ad2917531c - name: azurefile-csi-driver - urls: - - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/latest/azurefile-csi-driver-v1.26.1.tgz - version: v1.26.1 - - apiVersion: v1 - appVersion: v1.26.1 - created: "2023-02-16T07:31:47.28183659Z" + created: "2023-02-16T08:01:57.110770513Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: b1c78e2c38869f9430f3e2e671fb168db803eab2fbc0ef905eacdf8794d7968a name: azurefile-csi-driver @@ -21,7 +12,7 @@ entries: version: v1.26.1 - apiVersion: v1 appVersion: v1.26.0 - created: "2023-02-16T07:31:47.280446108Z" + created: "2023-02-16T08:01:57.109129555Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 98d15a8ced671a7c3d9aec8ebe00b58abeecb5f65ab966c9c01c4f39121adc0c name: azurefile-csi-driver @@ -30,7 +21,7 @@ entries: version: v1.26.0 - apiVersion: v1 appVersion: v1.25.1 - created: "2023-02-16T07:31:47.278883544Z" + created: "2023-02-16T08:01:57.108145943Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 2bf374cc321c5bc8e76e06cd5df85ce7d7d14574397e7e7f7173077393f554c4 name: azurefile-csi-driver @@ -39,7 +30,7 @@ entries: version: v1.25.1 - apiVersion: v1 appVersion: v1.25.0 - created: "2023-02-16T07:31:47.277769098Z" + created: "2023-02-16T08:01:57.107162319Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: ba80dcd23dade4e62b39d3dc638c599e9d5e100009fa14d4164bfc8966fea3dd name: azurefile-csi-driver @@ -48,7 +39,7 @@ entries: version: v1.25.0 - apiVersion: v1 appVersion: v1.24.0 - created: "2023-02-16T07:31:47.276565346Z" + created: "2023-02-16T08:01:57.106186704Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 1905eb862745d4a7f57c5de96848cee194adf827086984b75bcaefce5c90142b name: azurefile-csi-driver @@ -57,7 +48,7 @@ entries: version: v1.24.0 - apiVersion: v1 appVersion: v1.23.0 - created: "2023-02-16T07:31:47.275520175Z" + created: "2023-02-16T08:01:57.105191802Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 5fcb33617d16e90df1e7041b0df02e5bd92595e86381db30d356b0b2e3500bc4 name: azurefile-csi-driver @@ -66,7 +57,7 @@ entries: version: v1.23.0 - apiVersion: v1 appVersion: v1.22.0 - created: "2023-02-16T07:31:47.274026567Z" + created: "2023-02-16T08:01:57.103942117Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 253d87a8b876dbdd55870a7fee88547393179d03f193661125f5a0b63411f922 name: azurefile-csi-driver @@ -75,7 +66,7 @@ entries: version: v1.22.0 - apiVersion: v1 appVersion: v1.21.0 - created: "2023-02-16T07:31:47.272403178Z" + created: "2023-02-16T08:01:57.102490885Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: d45bf3455ebadc9cc5afaf9da66aa1ea1d4b719cfdff5af661f93bb26c01a504 name: azurefile-csi-driver @@ -84,7 +75,7 @@ entries: version: v1.21.0 - apiVersion: v1 appVersion: v1.20.0 - created: "2023-02-16T07:31:47.271424231Z" + created: "2023-02-16T08:01:57.101558031Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 7cc43d57a79137aea5414fb51a9bbd77bb679b29ee49c06865c1a5b9ba60be99 name: azurefile-csi-driver @@ -93,7 +84,7 @@ entries: version: v1.20.0 - apiVersion: v1 appVersion: v1.19.0 - created: "2023-02-16T07:31:47.269853632Z" + created: "2023-02-16T08:01:57.100151313Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 18f6efbed424efd661fde43be2e5a48a5012a46a7938c33b36963cbd9875a5af name: azurefile-csi-driver @@ -102,7 +93,7 @@ entries: version: v1.19.0 - apiVersion: v1 appVersion: v1.18.0 - created: "2023-02-16T07:31:47.268762331Z" + created: "2023-02-16T08:01:57.099230935Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 696ca23d9ee517f71ef5e852955c8d0f1017c331c025426c6fcbe7a06d006c66 name: azurefile-csi-driver @@ -111,7 +102,7 @@ entries: version: v1.18.0 - apiVersion: v1 appVersion: v1.17.0 - created: "2023-02-16T07:31:47.267668616Z" + created: "2023-02-16T08:01:57.098244027Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 5632f61265a3b78dce3e2b15e07cc9b14a7f54a778878c02ca2d9fe69ca0344e name: azurefile-csi-driver @@ -120,7 +111,7 @@ entries: version: v1.17.0 - apiVersion: v1 appVersion: v1.16.0 - created: "2023-02-16T07:31:47.265715467Z" + created: "2023-02-16T08:01:57.096515676Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: a7a2d57e8eca7dc06c8b2cffb9bccb857753eb110b8e70760b3e04f4e6a87552 name: azurefile-csi-driver @@ -129,7 +120,7 @@ entries: version: v1.16.0 - apiVersion: v1 appVersion: v1.15.0 - created: "2023-02-16T07:31:47.264535319Z" + created: "2023-02-16T08:01:57.095604911Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: c1a31dadce233a90c19dce70f6cc92ba2e20bbaa1b1883baea72381d09303118 name: azurefile-csi-driver @@ -138,7 +129,7 @@ entries: version: v1.15.0 - apiVersion: v1 appVersion: v1.14.0 - created: "2023-02-16T07:31:47.263472933Z" + created: "2023-02-16T08:01:57.094709756Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 0c9ad4afa5ebfdb2851ad93eb16a0382d61448714b7556899360730a2fdf463a name: azurefile-csi-driver @@ -147,7 +138,7 @@ entries: version: v1.14.0 - apiVersion: v1 appVersion: v1.13.0 - created: "2023-02-16T07:31:47.26241761Z" + created: "2023-02-16T08:01:57.093756882Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 214042b029d858b50a0f8bba33a7aa2b41d1b67bce16f957ca183ae7438dac3f name: azurefile-csi-driver @@ -156,7 +147,7 @@ entries: version: v1.13.0 - apiVersion: v1 appVersion: v1.12.0 - created: "2023-02-16T07:31:47.261429446Z" + created: "2023-02-16T08:01:57.092839402Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: fbd63929671066a26df898d32282a6e79c39499a39c71761c546d069459d847d name: azurefile-csi-driver @@ -165,7 +156,7 @@ entries: version: v1.12.0 - apiVersion: v1 appVersion: v1.11.0 - created: "2023-02-16T07:31:47.260310022Z" + created: "2023-02-16T08:01:57.091896686Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 76bd438f8391d08235b09fbca859f25a9fcf8e018fd1e7e33444ca9ea946ce4b name: azurefile-csi-driver @@ -174,7 +165,7 @@ entries: version: v1.11.0 - apiVersion: v1 appVersion: v1.10.0 - created: "2023-02-16T07:31:47.25827465Z" + created: "2023-02-16T08:01:57.089840631Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 845a9de8b571b255d05ae9c643d9b90a57fe6507ff3fb735c88b41f99f6f28dc name: azurefile-csi-driver @@ -183,7 +174,7 @@ entries: version: v1.10.0 - apiVersion: v1 appVersion: v1.9.0 - created: "2023-02-16T07:31:47.289624439Z" + created: "2023-02-16T08:01:57.117194875Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 59a8057fbbd6d59919b84ef0c3396d5a0a46d1f29df604457db676f4af63c714 name: azurefile-csi-driver @@ -192,7 +183,7 @@ entries: version: v1.9.0 - apiVersion: v1 appVersion: v1.8.0 - created: "2023-02-16T07:31:47.288267649Z" + created: "2023-02-16T08:01:57.115365174Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 455b7c342194311046df526d10926d94f3bef24f753a07003fb1cad211c4cb52 name: azurefile-csi-driver @@ -201,7 +192,7 @@ entries: version: v1.8.0 - apiVersion: v1 appVersion: v1.7.0 - created: "2023-02-16T07:31:47.286190248Z" + created: "2023-02-16T08:01:57.114407971Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 057b3f6ef6001d3457fbffc27f90316c981a089696abd3d38bcc8de5537dfa6f name: azurefile-csi-driver @@ -210,7 +201,7 @@ entries: version: v1.7.0 - apiVersion: v1 appVersion: v1.6.0 - created: "2023-02-16T07:31:47.284961365Z" + created: "2023-02-16T08:01:57.113621455Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: cc2a0dda824cdda4e8141e26878bbb481c5a52e45785a5dbf72e54f2a376e522 name: azurefile-csi-driver @@ -219,7 +210,7 @@ entries: version: v1.6.0 - apiVersion: v1 appVersion: v1.5.0 - created: "2023-02-16T07:31:47.284057281Z" + created: "2023-02-16T08:01:57.1129505Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 2258177477415ddecd83dc46dfd88833223623224c7fe396590b617082bcd845 name: azurefile-csi-driver @@ -228,7 +219,7 @@ entries: version: v1.5.0 - apiVersion: v1 appVersion: v1.4.0 - created: "2023-02-16T07:31:47.283241837Z" + created: "2023-02-16T08:01:57.112241153Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 40e9bc4ee187789166fcb7c3c82b85b33ecd3a6096266fe74e411d6b48961ece name: azurefile-csi-driver @@ -237,7 +228,7 @@ entries: version: v1.4.0 - apiVersion: v1 appVersion: v1.3.0 - created: "2023-02-16T07:31:47.282436878Z" + created: "2023-02-16T08:01:57.111572365Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 12942f422b7cccbfe950bbdbd5c844f5ae4b7c292f32389cba312730a6fe9a62 name: azurefile-csi-driver @@ -246,7 +237,7 @@ entries: version: v1.3.0 - apiVersion: v1 appVersion: v1.2.0 - created: "2023-02-16T07:31:47.270436553Z" + created: "2023-02-16T08:01:57.100644888Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: b62f44b757416a9e1f5a91e19285f5f5056ec6068802dd9cd82373bef40c9ee9 name: azurefile-csi-driver @@ -255,7 +246,7 @@ entries: version: v1.2.0 - apiVersion: v1 appVersion: v1.1.0 - created: "2023-02-16T07:31:47.257101093Z" + created: "2023-02-16T08:01:57.088788531Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 675d96b309a1c5c491053ebbb854c046737420929c4f0692839afdaaf0db3933 name: azurefile-csi-driver @@ -264,11 +255,20 @@ entries: version: v1.1.0 - apiVersion: v1 appVersion: v1.0.0 - created: "2023-02-16T07:31:47.256399049Z" + created: "2023-02-16T08:01:57.088290041Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 6fd5e54e949ef1061a08d5477bc580204c91dde8f01da195e95dd60ade209492 name: azurefile-csi-driver urls: - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/v1.0.0/azurefile-csi-driver-v1.0.0.tgz version: v1.0.0 -generated: "2023-02-16T07:31:47.254265709Z" + - apiVersion: v1 + appVersion: latest + created: "2023-02-16T08:01:57.087750805Z" + description: Azure File Container Storage Interface (CSI) Storage Plugin + digest: ebc1e5be3601a389421aa569e485b7bcee9f79ae7bea6b2075150bfcacf99fa0 + name: azurefile-csi-driver + urls: + - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/latest/azurefile-csi-driver-v0.0.0.tgz + version: v0.0.0 +generated: "2023-02-16T08:01:57.086543516Z" diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..18afec5b8e89c9e4db8e3a9dd3b3607bc3144f3a GIT binary patch literal 11434 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 literal 0 HcmV?d00001 diff --git a/charts/latest/azurefile-csi-driver-v1.26.1.tgz b/charts/latest/azurefile-csi-driver-v1.26.1.tgz deleted file mode 100644 index d03a27174db258d974565f4028fcd00ebaab3bc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11419 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 BpP~Q& diff --git a/charts/latest/azurefile-csi-driver/Chart.yaml b/charts/latest/azurefile-csi-driver/Chart.yaml index 630811bca8..27ff7d757c 100644 --- a/charts/latest/azurefile-csi-driver/Chart.yaml +++ b/charts/latest/azurefile-csi-driver/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: v1.26.1 +appVersion: latest description: Azure File Container Storage Interface (CSI) Storage Plugin name: azurefile-csi-driver -version: v1.26.1 +version: v0.0.0 diff --git a/charts/latest/azurefile-csi-driver/values.yaml b/charts/latest/azurefile-csi-driver/values.yaml index f290d24ee6..50f8a7c731 100644 --- a/charts/latest/azurefile-csi-driver/values.yaml +++ b/charts/latest/azurefile-csi-driver/values.yaml @@ -1,8 +1,8 @@ image: baseRepo: mcr.microsoft.com azurefile: - repository: /oss/kubernetes-csi/azurefile-csi - tag: v1.26.1 + repository: /k8s/csi/azurefile-csi + tag: latest pullPolicy: IfNotPresent csiProvisioner: repository: /oss/kubernetes-csi/csi-provisioner diff --git a/deploy/csi-azurefile-controller.yaml b/deploy/csi-azurefile-controller.yaml index 71e8da9221..623890f3ee 100644 --- a/deploy/csi-azurefile-controller.yaml +++ b/deploy/csi-azurefile-controller.yaml @@ -133,7 +133,7 @@ spec: cpu: 10m memory: 20Mi - name: azurefile - image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.1 + image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest imagePullPolicy: IfNotPresent args: - "--v=5" diff --git a/deploy/csi-azurefile-driver.yaml b/deploy/csi-azurefile-driver.yaml index 0b4ecbbe26..55d31ed2d1 100644 --- a/deploy/csi-azurefile-driver.yaml +++ b/deploy/csi-azurefile-driver.yaml @@ -4,7 +4,7 @@ kind: CSIDriver metadata: name: file.csi.azure.com annotations: - csiDriver: v1.26.1 + csiDriver: latest snapshot: v5.0.1 spec: attachRequired: false diff --git a/deploy/csi-azurefile-node-windows.yaml b/deploy/csi-azurefile-node-windows.yaml index 11d1891cf8..9340864653 100644 --- a/deploy/csi-azurefile-node-windows.yaml +++ b/deploy/csi-azurefile-node-windows.yaml @@ -91,7 +91,7 @@ spec: cpu: 30m memory: 40Mi - name: azurefile - image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.1 + image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest imagePullPolicy: IfNotPresent args: - --v=5 diff --git a/deploy/csi-azurefile-node.yaml b/deploy/csi-azurefile-node.yaml index c7f63edd00..f36a6a9545 100644 --- a/deploy/csi-azurefile-node.yaml +++ b/deploy/csi-azurefile-node.yaml @@ -82,7 +82,7 @@ spec: cpu: 10m memory: 20Mi - name: azurefile - image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.1 + image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest imagePullPolicy: IfNotPresent args: - "--v=5" From bcc6818ef3de4a0bc30b98c20bd96c53a177759a Mon Sep 17 00:00:00 2001 From: Ji An Liu Date: Fri, 10 Feb 2023 00:48:59 +0000 Subject: [PATCH 025/109] support to enable windows process Signed-off-by: Ji An Liu --- pkg/azurefile/azurefile.go | 5 +- pkg/azurefile/fake_mounter.go | 2 +- pkg/azurefileplugin/main.go | 2 + .../safe_mounter_host_process_windows.go | 268 ++++++++++++++++++ pkg/mounter/safe_mounter_unix.go | 2 +- pkg/mounter/safe_mounter_unix_test.go | 5 +- pkg/mounter/safe_mounter_windows.go | 9 +- pkg/os/filesystem/filesystem.go | 251 ++++++++++++++++ pkg/os/filesystem/types.go | 143 ++++++++++ pkg/os/smb/smb.go | 99 +++++++ pkg/util/util.go | 3 +- 11 files changed, 782 insertions(+), 7 deletions(-) create mode 100644 pkg/mounter/safe_mounter_host_process_windows.go create mode 100644 pkg/os/filesystem/filesystem.go create mode 100644 pkg/os/filesystem/types.go create mode 100644 pkg/os/smb/smb.go diff --git a/pkg/azurefile/azurefile.go b/pkg/azurefile/azurefile.go index b888287019..d4c19d8cd5 100644 --- a/pkg/azurefile/azurefile.go +++ b/pkg/azurefile/azurefile.go @@ -197,6 +197,7 @@ type DriverOptions struct { FSGroupChangePolicy string KubeAPIQPS float64 KubeAPIBurst int + EnableWindowsHostProcess bool } // Driver implements all interfaces of CSI drivers @@ -216,6 +217,7 @@ type Driver struct { mountPermissions uint64 kubeAPIQPS float64 kubeAPIBurst int + enableWindowsHostProcess bool fileClient *azureFileClient mounter *mount.SafeFormatAndMount // lock per volume attach (only for vhd disk feature) @@ -261,6 +263,7 @@ func NewDriver(options *DriverOptions) *Driver { driver.fsGroupChangePolicy = options.FSGroupChangePolicy driver.kubeAPIQPS = options.KubeAPIQPS driver.kubeAPIBurst = options.KubeAPIBurst + driver.enableWindowsHostProcess = options.EnableWindowsHostProcess driver.volLockMap = newLockMap() driver.subnetLockMap = newLockMap() driver.volumeLocks = newVolumeLocks() @@ -310,7 +313,7 @@ func (d *Driver) Run(endpoint, kubeconfig string, testBool bool) { // todo: set backoff from cloud provider config d.fileClient = newAzureFileClient(&d.cloud.Environment, &retry.Backoff{Steps: 1}) - d.mounter, err = mounter.NewSafeMounter() + d.mounter, err = mounter.NewSafeMounter(d.enableWindowsHostProcess) if err != nil { klog.Fatalf("Failed to get safe mounter. Error: %v", err) } diff --git a/pkg/azurefile/fake_mounter.go b/pkg/azurefile/fake_mounter.go index 7652ca164f..730ae87022 100644 --- a/pkg/azurefile/fake_mounter.go +++ b/pkg/azurefile/fake_mounter.go @@ -74,7 +74,7 @@ func (f *fakeMounter) IsMountPoint(file string) (bool, error) { // NewFakeMounter fake mounter func NewFakeMounter() (*mount.SafeFormatAndMount, error) { if runtime.GOOS == "windows" { - return mounter.NewSafeMounter() + return mounter.NewSafeMounter(false) } return &mount.SafeFormatAndMount{ Interface: &fakeMounter{}, diff --git a/pkg/azurefileplugin/main.go b/pkg/azurefileplugin/main.go index 146ee02a40..55f7144b39 100644 --- a/pkg/azurefileplugin/main.go +++ b/pkg/azurefileplugin/main.go @@ -55,6 +55,7 @@ var ( kubeAPIQPS = flag.Float64("kube-api-qps", 25.0, "QPS to use while communicating with the kubernetes apiserver.") kubeAPIBurst = flag.Int("kube-api-burst", 50, "Burst to use while communicating with the kubernetes apiserver.") appendMountErrorHelpLink = flag.Bool("append-mount-error-help-link", true, "Whether to include a link for help with mount errors when a mount error occurs.") + enableWindowsHostProcess = flag.Bool("enable-windows-host-process", false, "enable windows host process") ) func main() { @@ -95,6 +96,7 @@ func handle() { AppendMountErrorHelpLink: *appendMountErrorHelpLink, KubeAPIQPS: *kubeAPIQPS, KubeAPIBurst: *kubeAPIBurst, + EnableWindowsHostProcess: *enableWindowsHostProcess, } driver := azurefile.NewDriver(&driverOptions) if driver == nil { diff --git a/pkg/mounter/safe_mounter_host_process_windows.go b/pkg/mounter/safe_mounter_host_process_windows.go new file mode 100644 index 0000000000..bacb57baaa --- /dev/null +++ b/pkg/mounter/safe_mounter_host_process_windows.go @@ -0,0 +1,268 @@ +//go:build windows +// +build windows + +/* +Copyright 2022 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 mounter + +import ( + "context" + "fmt" + "os" + filepath "path/filepath" + "strings" + + "k8s.io/klog/v2" + mount "k8s.io/mount-utils" + + "sigs.k8s.io/azurefile-csi-driver/pkg/os/filesystem" + "sigs.k8s.io/azurefile-csi-driver/pkg/os/smb" +) + +var _ CSIProxyMounter = &winMounter{} + +type winMounter struct{} + +func NewWinMounter() *winMounter { + return &winMounter{} +} + +func (mounter *winMounter) SMBMount(source, target, fsType string, mountOptions, sensitiveMountOptions []string) error { + klog.V(2).Infof("SMBMount: remote path: %s local path: %s", source, target) + + if len(mountOptions) == 0 || len(sensitiveMountOptions) == 0 { + return fmt.Errorf("empty mountOptions(len: %d) or sensitiveMountOptions(len: %d) is not allowed", len(mountOptions), len(sensitiveMountOptions)) + } + + parentDir := filepath.Dir(target) + parentExists, err := mounter.ExistsPath(parentDir) + if err != nil { + return fmt.Errorf("parent dir: %s exist check failed with err: %v", parentDir, err) + } + + if !parentExists { + klog.V(2).Infof("Parent directory %s does not exists. Creating the directory", parentDir) + if err := mounter.MakeDir(parentDir); err != nil { + return fmt.Errorf("create of parent dir: %s dailed with error: %v", parentDir, err) + } + } + + source = strings.Replace(source, "/", "\\", -1) + normalizedTarget := normalizeWindowsPath(target) + + klog.V(2).Infof("begin to mount %s on %s", source, normalizedTarget) + + remotePath := source + localPath := normalizedTarget + + if remotePath == "" { + klog.Errorf("remote path is empty") + return fmt.Errorf("remote path is empty") + } + + isMapped, err := smb.IsSmbMapped(remotePath) + if err != nil { + isMapped = false + } + + if isMapped { + valid, err := filesystem.PathValid(context.Background(), remotePath) + if err != nil { + klog.Warningf("PathValid(%s) failed with %v, ignore error", remotePath, err) + } + + if !valid { + klog.V(4).Infof("RemotePath %s is not valid, removing now", remotePath) + err := smb.RemoveSmbGlobalMapping(remotePath) + if err != nil { + klog.Errorf("RemoveSmbGlobalMapping(%s) failed with %v", remotePath, err) + return err + } + isMapped = false + } + } + + if !isMapped { + klog.V(4).Infof("Remote %s not mapped. Mapping now!", remotePath) + username := mountOptions[0] + password := sensitiveMountOptions[0] + err := smb.NewSmbGlobalMapping(remotePath, username, password) + if err != nil { + klog.Errorf("failed NewSmbGlobalMapping %v", err) + return err + } + } + + if len(localPath) != 0 { + err = filesystem.ValidatePathWindows(localPath) + if err != nil { + klog.Errorf("failed validate plugin path %v", err) + return err + } + err = smb.NewSmbLink(remotePath, localPath) + if err != nil { + klog.Errorf("failed NewSmbLink %v", err) + return fmt.Errorf("creating link %s to %s failed with error: %v", localPath, remotePath, err) + } + } + + klog.V(2).Infof("mount %s on %s successfully", source, normalizedTarget) + + return nil +} + +func (mounter *winMounter) SMBUnmount(target string) error { + klog.V(4).Infof("SMBUnmount: local path: %s", target) + return mounter.Rmdir(target) +} + +// Mount just creates a soft link at target pointing to source. +func (mounter *winMounter) Mount(source string, target string, fstype string, options []string) error { + klog.V(4).Infof("Mount: old name: %s. new name: %s", source, target) + // Mount is called after the format is done. + // TODO: Confirm that fstype is empty. + linkRequest := &filesystem.LinkPathRequest{ + SourcePath: normalizeWindowsPath(source), + TargetPath: normalizeWindowsPath(target), + } + if err := filesystem.LinkPath(context.Background(), linkRequest); err != nil { + return err + } + return nil +} + +// Rmdir - delete the given directory +func (mounter *winMounter) Rmdir(path string) error { + klog.V(4).Infof("Remove directory: %s", path) + rmdirRequest := &filesystem.RmdirRequest{ + Path: normalizeWindowsPath(path), + Force: true, + } + if err := filesystem.Rmdir(context.Background(), rmdirRequest); err != nil { + return err + } + return nil +} + +// Unmount - Removes the directory - equivalent to unmount on Linux. +func (mounter *winMounter) Unmount(target string) error { + klog.V(4).Infof("Unmount: %s", target) + return mounter.Rmdir(target) +} + +func (mounter *winMounter) List() ([]mount.MountPoint, error) { + return []mount.MountPoint{}, fmt.Errorf("List not implemented for CSIProxyMounter") +} + +func (mounter *winMounter) IsMountPoint(file string) (bool, error) { + isNotMnt, err := mounter.IsLikelyNotMountPoint(file) + if err != nil { + return false, err + } + return !isNotMnt, nil +} + +func (mounter *winMounter) IsMountPointMatch(mp mount.MountPoint, dir string) bool { + return mp.Path == dir +} + +// IsLikelyMountPoint - If the directory does not exists, the function will return os.ErrNotExist error. +// If the path exists, will check if its a link, if its a link then existence of target path is checked. +func (mounter *winMounter) IsLikelyNotMountPoint(path string) (bool, error) { + klog.V(4).Infof("IsLikelyNotMountPoint: %s", path) + isExists, err := mounter.ExistsPath(path) + if err != nil { + return false, err + } + if !isExists { + return true, os.ErrNotExist + } + + response, err := filesystem.IsMountPoint(context.Background(), + &filesystem.IsMountPointRequest{ + Path: normalizeWindowsPath(path), + }) + if err != nil { + return false, err + } + return !response, nil +} + +// MakeDir - Creates a directory. +// Currently the make dir is only used from the staging code path, hence we call it +// with Plugin context.. +func (mounter *winMounter) MakeDir(path string) error { + klog.V(4).Infof("Make directory: %s", path) + mkdirReq := &filesystem.MkdirRequest{ + Path: normalizeWindowsPath(path), + } + if err := filesystem.Mkdir(context.Background(), mkdirReq); err != nil { + return err + } + + return nil +} + +// ExistsPath - Checks if a path exists. Unlike util ExistsPath, this call does not perform follow link. +func (mounter *winMounter) ExistsPath(path string) (bool, error) { + klog.V(4).Infof("Exists path: %s", path) + return filesystem.PathExists(context.Background(), + &filesystem.PathExistsRequest{ + Path: normalizeWindowsPath(path), + }) +} + +func (mounter *winMounter) MountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error { + return fmt.Errorf("MountSensitive not implemented for winMounter") +} + +func (mounter *winMounter) MountSensitiveWithoutSystemd(source string, target string, fstype string, options []string, sensitiveOptions []string) error { + return fmt.Errorf("MountSensitiveWithoutSystemd not implemented for winMounter") +} + +func (mounter *winMounter) MountSensitiveWithoutSystemdWithMountFlags(source string, target string, fstype string, options []string, sensitiveOptions []string, mountFlags []string) error { + return mounter.MountSensitive(source, target, fstype, options, sensitiveOptions /* sensitiveOptions */) +} + +func (mounter *winMounter) GetMountRefs(pathname string) ([]string, error) { + return []string{}, fmt.Errorf("GetMountRefs not implemented for winMounter") +} + +func (mounter *winMounter) EvalHostSymlinks(pathname string) (string, error) { + return "", fmt.Errorf("EvalHostSymlinks not implemented for winMounter") +} + +func (mounter *winMounter) GetFSGroup(pathname string) (int64, error) { + return -1, fmt.Errorf("GetFSGroup not implemented for winMounter") +} + +func (mounter *winMounter) GetSELinuxSupport(pathname string) (bool, error) { + return false, fmt.Errorf("GetSELinuxSupport not implemented for winMounter") +} + +func (mounter *winMounter) GetMode(pathname string) (os.FileMode, error) { + return 0, fmt.Errorf("GetMode not implemented for winMounter") +} + +// GetAPIVersions returns the versions of the client APIs this mounter is using. +func (mounter *winMounter) GetAPIVersions() string { + return "" +} + +func (mounter *winMounter) CanSafelySkipMountPointCheck() bool { + return false +} diff --git a/pkg/mounter/safe_mounter_unix.go b/pkg/mounter/safe_mounter_unix.go index d5ee4d14a8..38b94b2a0c 100644 --- a/pkg/mounter/safe_mounter_unix.go +++ b/pkg/mounter/safe_mounter_unix.go @@ -24,7 +24,7 @@ import ( utilexec "k8s.io/utils/exec" ) -func NewSafeMounter() (*mount.SafeFormatAndMount, error) { +func NewSafeMounter(enableWindowsHostProcess bool) (*mount.SafeFormatAndMount, error) { return &mount.SafeFormatAndMount{ Interface: mount.New(""), Exec: utilexec.New(), diff --git a/pkg/mounter/safe_mounter_unix_test.go b/pkg/mounter/safe_mounter_unix_test.go index 9acf46780d..913d5d5693 100644 --- a/pkg/mounter/safe_mounter_unix_test.go +++ b/pkg/mounter/safe_mounter_unix_test.go @@ -17,12 +17,13 @@ limitations under the License. package mounter import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestNewSafeMounter(t *testing.T) { - resp, err := NewSafeMounter() + resp, err := NewSafeMounter(false) assert.NotNil(t, resp) assert.Nil(t, err) } diff --git a/pkg/mounter/safe_mounter_windows.go b/pkg/mounter/safe_mounter_windows.go index 61d76b0156..6c99c9a027 100644 --- a/pkg/mounter/safe_mounter_windows.go +++ b/pkg/mounter/safe_mounter_windows.go @@ -291,7 +291,14 @@ func NewCSIProxyMounter() (*csiProxyMounter, error) { }, nil } -func NewSafeMounter() (*mount.SafeFormatAndMount, error) { +func NewSafeMounter(enableWindowsHostProcess bool) (*mount.SafeFormatAndMount, error) { + if enableWindowsHostProcess { + klog.V(2).Infof("using windows host process mounter") + return &mount.SafeFormatAndMount{ + Interface: NewWinMounter(), + Exec: utilexec.New(), + }, nil + } csiProxyMounter, err := NewCSIProxyMounter() if err == nil { klog.V(2).Infof("using CSIProxyMounterV1, %s", csiProxyMounter.GetAPIVersions()) diff --git a/pkg/os/filesystem/filesystem.go b/pkg/os/filesystem/filesystem.go new file mode 100644 index 0000000000..0db89d8552 --- /dev/null +++ b/pkg/os/filesystem/filesystem.go @@ -0,0 +1,251 @@ +/* +Copyright 2023 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 filesystem + +import ( + "context" + "fmt" + "os" + "os/exec" + "regexp" + "strings" + + "k8s.io/klog/v2" + "sigs.k8s.io/azurefile-csi-driver/pkg/util" +) + +var invalidPathCharsRegexWindows = regexp.MustCompile(`["/\:\?\*|]`) +var absPathRegexWindows = regexp.MustCompile(`^[a-zA-Z]:\\`) + +func containsInvalidCharactersWindows(path string) bool { + if isAbsWindows(path) { + path = path[3:] + } + if invalidPathCharsRegexWindows.MatchString(path) { + return true + } + if strings.Contains(path, `..`) { + return true + } + return false +} + +func isUNCPathWindows(path string) bool { + // check for UNC/pipe prefixes like "\\" + if len(path) < 2 { + return false + } + if path[0] == '\\' && path[1] == '\\' { + return true + } + return false +} + +func isAbsWindows(path string) bool { + // for Windows check for C:\\.. prefix only + // UNC prefixes of the form \\ are not considered + return absPathRegexWindows.MatchString(path) +} + +func pathExists(path string) (bool, error) { + _, err := os.Lstat(path) + if err == nil { + return true, nil + } + if os.IsNotExist(err) { + return false, nil + } + return false, err +} + +// PathExists checks if the given path exists on the host. +func PathExists(ctx context.Context, request *PathExistsRequest) (bool, error) { + klog.V(2).Infof("Request: PathExists with path=%q", request.Path) + err := ValidatePathWindows(request.Path) + if err != nil { + klog.Errorf("failed validatePathWindows %v", err) + return false, err + } + exists, err := pathExists(request.Path) + if err != nil { + klog.Errorf("failed check PathExists %v", err) + } + return exists, err +} + +func PathValid(ctx context.Context, path string) (bool, error) { + cmd := exec.Command("powershell", "/c", `Test-Path $Env:remotepath`) + cmd.Env = append(os.Environ(), fmt.Sprintf("remotepath=%s", path)) + output, err := cmd.CombinedOutput() + if err != nil { + return false, fmt.Errorf("returned output: %s, error: %v", string(output), err) + } + + return strings.HasPrefix(strings.ToLower(string(output)), "true"), nil +} + +func ValidatePathWindows(path string) error { + prefix := `C:\var\lib\kubelet` + + pathlen := len(path) + + if pathlen > util.MaxPathLengthWindows { + return fmt.Errorf("path length %d exceeds maximum characters: %d", pathlen, util.MaxPathLengthWindows) + } + + if pathlen > 0 && (path[0] == '\\') { + return fmt.Errorf("invalid character \\ at beginning of path: %s", path) + } + + if isUNCPathWindows(path) { + return fmt.Errorf("unsupported UNC path prefix: %s", path) + } + + if containsInvalidCharactersWindows(path) { + return fmt.Errorf("path contains invalid characters: %s", path) + } + + if !isAbsWindows(path) { + return fmt.Errorf("not an absolute Windows path: %s", path) + } + + if !strings.HasPrefix(strings.ToLower(path), strings.ToLower(prefix)) { + return fmt.Errorf("path: %s is not within context path: %s", path, prefix) + } + + return nil +} + +func Mkdir(ctx context.Context, request *MkdirRequest) error { + klog.V(2).Infof("Request: Mkdir with path=%q", request.Path) + err := ValidatePathWindows(request.Path) + if err != nil { + klog.Errorf("failed validatePathWindows %v", err) + return err + } + err = os.MkdirAll(request.Path, 0755) + if err != nil { + klog.Errorf("failed Mkdir %v", err) + return err + } + + return err +} + +func Rmdir(ctx context.Context, request *RmdirRequest) error { + klog.V(2).Infof("Request: Rmdir with path=%q", request.Path) + err := ValidatePathWindows(request.Path) + if err != nil { + klog.Errorf("failed validatePathWindows %v", err) + return err + } + + if request.Force { + err = os.RemoveAll(request.Path) + } else { + err = os.Remove(request.Path) + } + if err != nil { + klog.Errorf("failed Rmdir %v", err) + return err + } + + return err +} +func LinkPath(ctx context.Context, request *LinkPathRequest) error { + klog.V(2).Infof("Request: LinkPath with targetPath=%q sourcePath=%q", request.TargetPath, request.SourcePath) + createSymlinkRequest := &CreateSymlinkRequest{ + SourcePath: request.SourcePath, + TargetPath: request.TargetPath, + } + if err := CreateSymlink(ctx, createSymlinkRequest); err != nil { + klog.Errorf("Failed to forward to CreateSymlink: %v", err) + return err + } + return nil +} + +func CreateSymlink(ctx context.Context, request *CreateSymlinkRequest) error { + klog.V(2).Infof("Request: CreateSymlink with targetPath=%q sourcePath=%q", request.TargetPath, request.SourcePath) + err := ValidatePathWindows(request.TargetPath) + if err != nil { + klog.Errorf("failed validatePathWindows for target path %v", err) + return err + } + err = ValidatePathWindows(request.SourcePath) + if err != nil { + klog.Errorf("failed validatePathWindows for source path %v", err) + return err + } + err = os.Symlink(request.SourcePath, request.TargetPath) + if err != nil { + klog.Errorf("failed CreateSymlink: %v", err) + return err + } + return nil +} + +func IsMountPoint(ctx context.Context, request *IsMountPointRequest) (bool, error) { + klog.V(2).Infof("Request: IsMountPoint with path=%q", request.Path) + isSymlinkRequest := &IsSymlinkRequest{ + Path: request.Path, + } + isSymlink, err := IsSymlink(ctx, isSymlinkRequest) + if err != nil { + klog.Errorf("Failed to forward to IsSymlink: %v", err) + } + return isSymlink, err +} + +func IsSymlink(ctx context.Context, request *IsSymlinkRequest) (bool, error) { + klog.V(2).Infof("Request: IsSymlink with path=%q", request.Path) + isSymlink, err := isSymlink(request.Path) + if err != nil { + klog.Errorf("failed IsSymlink %v", err) + } + return isSymlink, err +} + +// IsSymlink - returns true if tgt is a mount point. +// A path is considered a mount point if: +// - directory exists and +// - it is a soft link and +// - the target path of the link exists. +// If tgt path does not exist, it returns an error +// if tgt path exists, but the source path tgt points to does not exist, it returns false without error. +func isSymlink(tgt string) (bool, error) { + // This code is similar to k8s.io/kubernetes/pkg/util/mount except the pathExists usage. + stat, err := os.Lstat(tgt) + if err != nil { + return false, err + } + + // If its a link and it points to an existing file then its a mount point. + if stat.Mode()&os.ModeSymlink != 0 { + target, err := os.Readlink(tgt) + if err != nil { + return false, fmt.Errorf("readlink error: %v", err) + } + exists, err := pathExists(target) + if err != nil { + return false, err + } + return exists, nil + } + + return false, nil +} diff --git a/pkg/os/filesystem/types.go b/pkg/os/filesystem/types.go new file mode 100644 index 0000000000..208fe50f25 --- /dev/null +++ b/pkg/os/filesystem/types.go @@ -0,0 +1,143 @@ +/* +Copyright 2023 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 filesystem + +type PathExistsRequest struct { + // The path whose existence we want to check in the host's filesystem + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` +} + +type MkdirRequest struct { + // The path to create in the host's filesystem. + // All special characters allowed by Windows in path names will be allowed + // except for restrictions noted below. For details, please check: + // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file + // Non-existent parent directories in the path will be automatically created. + // Directories will be created with Read and Write privileges of the Windows + // User account under which csi-proxy is started (typically LocalSystem). + // + // Restrictions: + // Only absolute path (indicated by a drive letter prefix: e.g. "C:\") is accepted. + // Depending on the context parameter of this function, the path prefix needs + // to match the paths specified either as kubelet-csi-plugins-path + // or as kubelet-pod-path parameters of csi-proxy. + // The path parameter cannot already exist in the host's filesystem. + // UNC paths of the form "\\server\share\path\file" are not allowed. + // All directory separators need to be backslash character: "\". + // Characters: .. / : | ? * in the path are not allowed. + // Maximum path length will be capped to 260 characters. + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` +} + +type RmdirRequest struct { + // The path to remove in the host's filesystem. + // All special characters allowed by Windows in path names will be allowed + // except for restrictions noted below. For details, please check: + // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file + // + // Restrictions: + // Only absolute path (indicated by a drive letter prefix: e.g. "C:\") is accepted. + // Depending on the context parameter of this function, the path prefix needs + // to match the paths specified either as kubelet-csi-plugins-path + // or as kubelet-pod-path parameters of csi-proxy. + // UNC paths of the form "\\server\share\path\file" are not allowed. + // All directory separators need to be backslash character: "\". + // Characters: .. / : | ? * in the path are not allowed. + // Path cannot be a file of type symlink. + // Maximum path length will be capped to 260 characters. + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + // Force remove all contents under path (if any). + Force bool `protobuf:"varint,2,opt,name=force,proto3" json:"force,omitempty"` +} + +type LinkPathRequest struct { + // The path where the symlink is created in the host's filesystem. + // All special characters allowed by Windows in path names will be allowed + // except for restrictions noted below. For details, please check: + // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file + // + // Restrictions: + // Only absolute path (indicated by a drive letter prefix: e.g. "C:\") is accepted. + // The path prefix needs to match the paths specified as + // kubelet-csi-plugins-path parameter of csi-proxy. + // UNC paths of the form "\\server\share\path\file" are not allowed. + // All directory separators need to be backslash character: "\". + // Characters: .. / : | ? * in the path are not allowed. + // source_path cannot already exist in the host filesystem. + // Maximum path length will be capped to 260 characters. + SourcePath string `protobuf:"bytes,1,opt,name=source_path,json=sourcePath,proto3" json:"source_path,omitempty"` + // Target path in the host's filesystem used for the symlink creation. + // All special characters allowed by Windows in path names will be allowed + // except for restrictions noted below. For details, please check: + // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file + // + // Restrictions: + // Only absolute path (indicated by a drive letter prefix: e.g. "C:\") is accepted. + // The path prefix needs to match the paths specified as + // kubelet-pod-path parameter of csi-proxy. + // UNC paths of the form "\\server\share\path\file" are not allowed. + // All directory separators need to be backslash character: "\". + // Characters: .. / : | ? * in the path are not allowed. + // target_path needs to exist as a directory in the host that is empty. + // target_path cannot be a symbolic link. + // Maximum path length will be capped to 260 characters. + TargetPath string `protobuf:"bytes,2,opt,name=target_path,json=targetPath,proto3" json:"target_path,omitempty"` +} + +type CreateSymlinkRequest struct { + // The path of the existing directory to be linked. + // All special characters allowed by Windows in path names will be allowed + // except for restrictions noted below. For details, please check: + // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file + // + // Restrictions: + // Only absolute path (indicated by a drive letter prefix: e.g. "C:\") is accepted. + // The path prefix needs needs to match the paths specified as + // kubelet-csi-plugins-path parameter of csi-proxy. + // UNC paths of the form "\\server\share\path\file" are not allowed. + // All directory separators need to be backslash character: "\". + // Characters: .. / : | ? * in the path are not allowed. + // source_path cannot already exist in the host filesystem. + // Maximum path length will be capped to 260 characters. + SourcePath string `protobuf:"bytes,1,opt,name=source_path,json=sourcePath,proto3" json:"source_path,omitempty"` + // Target path is the location of the new directory entry to be created in the host's filesystem. + // All special characters allowed by Windows in path names will be allowed + // except for restrictions noted below. For details, please check: + // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file + // + // Restrictions: + // Only absolute path (indicated by a drive letter prefix: e.g. "C:\") is accepted. + // The path prefix needs to match the paths specified as + // kubelet-pod-path parameter of csi-proxy. + // UNC paths of the form "\\server\share\path\file" are not allowed. + // All directory separators need to be backslash character: "\". + // Characters: .. / : | ? * in the path are not allowed. + // target_path needs to exist as a directory in the host that is empty. + // target_path cannot be a symbolic link. + // Maximum path length will be capped to 260 characters. + TargetPath string `protobuf:"bytes,2,opt,name=target_path,json=targetPath,proto3" json:"target_path,omitempty"` +} + +type IsMountPointRequest struct { + // The path whose existence we want to check in the host's filesystem + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` +} + +type IsSymlinkRequest struct { + // The path whose existence as a symlink we want to check in the host's filesystem. + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` +} diff --git a/pkg/os/smb/smb.go b/pkg/os/smb/smb.go new file mode 100644 index 0000000000..7aa7ecb831 --- /dev/null +++ b/pkg/os/smb/smb.go @@ -0,0 +1,99 @@ +/* +Copyright 2023 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 smb + +import ( + "fmt" + "os" + "os/exec" + "strings" +) + +func IsSmbMapped(remotePath string) (bool, error) { + cmdLine := fmt.Sprintf(`$(Get-SmbGlobalMapping -RemotePath $Env:smbremotepath -ErrorAction Stop).Status `) + cmd := exec.Command("powershell", "/c", cmdLine) + cmd.Env = append(os.Environ(), + fmt.Sprintf("smbremotepath=%s", remotePath)) + + out, err := cmd.CombinedOutput() + if err != nil { + return false, fmt.Errorf("error checking smb mapping. cmd %s, output: %s, err: %v", remotePath, string(out), err) + } + + if len(out) == 0 || !strings.EqualFold(strings.TrimSpace(string(out)), "OK") { + return false, nil + } + return true, nil +} + +// NewSmbLink - creates a directory symbolic link to the remote share. +// The os.Symlink was having issue for cases where the destination was an SMB share - the container +// runtime would complain stating "Access Denied". Because of this, we had to perform +// this operation with powershell commandlet creating an directory softlink. +// Since os.Symlink is currently being used in working code paths, no attempt is made in +// alpha to merge the paths. +func NewSmbLink(remotePath, localPath string) error { + + if !strings.HasSuffix(remotePath, "\\") { + // Golang has issues resolving paths mapped to file shares if they do not end in a trailing \ + // so add one if needed. + remotePath = remotePath + "\\" + } + + cmdLine := fmt.Sprintf(`New-Item -ItemType SymbolicLink $Env:smblocalPath -Target $Env:smbremotepath`) + cmd := exec.Command("powershell", "/c", cmdLine) + cmd.Env = append(os.Environ(), + fmt.Sprintf("smbremotepath=%s", remotePath), + fmt.Sprintf("smblocalpath=%s", localPath), + ) + output, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("error linking %s to %s. output: %s, err: %v", remotePath, localPath, string(output), err) + } + + return nil +} + +func NewSmbGlobalMapping(remotePath, username, password string) error { + + // use PowerShell Environment Variables to store user input string to prevent command line injection + // https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_environment_variables?view=powershell-5.1 + cmdLine := fmt.Sprintf(`$PWord = ConvertTo-SecureString -String $Env:smbpassword -AsPlainText -Force` + + `;$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Env:smbuser, $PWord` + + `;New-SmbGlobalMapping -RemotePath $Env:smbremotepath -Credential $Credential`) + + cmd := exec.Command("powershell", "/c", cmdLine) + cmd.Env = append(os.Environ(), + fmt.Sprintf("smbuser=%s", username), + fmt.Sprintf("smbpassword=%s", password), + fmt.Sprintf("smbremotepath=%s", remotePath)) + + if output, err := cmd.CombinedOutput(); err != nil { + return fmt.Errorf("NewSmbGlobalMapping failed. output: %q, err: %v\n[debug]smbuser=%s,smbpassword=%s,smbremotepath=%s", string(output), err, username, password, remotePath) + } + + return nil +} + +func RemoveSmbGlobalMapping(remotePath string) error { + cmd := exec.Command("powershell", "/c", `Remove-SmbGlobalMapping -RemotePath $Env:smbremotepath -Force`) + cmd.Env = append(os.Environ(), fmt.Sprintf("smbremotepath=%s", remotePath)) + if output, err := cmd.CombinedOutput(); err != nil { + return fmt.Errorf("UnmountSmbShare failed. output: %q, err: %v", string(output), err) + } + return nil +} diff --git a/pkg/util/util.go b/pkg/util/util.go index aa906cea9a..65e331f9b3 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -17,7 +17,8 @@ limitations under the License. package util const ( - GiB = 1024 * 1024 * 1024 + GiB = 1024 * 1024 * 1024 + MaxPathLengthWindows = 260 ) // RoundUpBytes rounds up the volume size in bytes up to multiplications of GiB From 161e037389f3837d725db0e3d51b0e536bca8205 Mon Sep 17 00:00:00 2001 From: Andy Zhang Date: Fri, 17 Feb 2023 11:16:09 +0800 Subject: [PATCH 026/109] chore: switch master branch version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index db8a1cf572..7edb94145b 100755 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ GIT_COMMIT ?= $(shell git rev-parse HEAD) REGISTRY ?= andyzhangx REGISTRY_NAME ?= $(shell echo $(REGISTRY) | sed "s/.azurecr.io//g") IMAGE_NAME ?= azurefile-csi -IMAGE_VERSION ?= v1.26.0 +IMAGE_VERSION ?= v1.27.0 # Use a custom version for E2E tests if we are testing in CI ifdef CI ifndef PUBLISH From 64dec3460c9934efc84798720d614a6eef988a21 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Fri, 17 Feb 2023 13:32:00 +0000 Subject: [PATCH 027/109] doc: remove accountAccessTier in doc since it's only for blob storagedoc: remove accountAccessTier in doc since it's only for blob storagedoc: remove accountAccessTier in doc since it's only for blob storagedoc: remove accountAccessTier in doc since it's only for blob storagedoc: remove accountAccessTier in doc since it's only for blob storagedoc: remove accountAccessTier in doc since it's only for blob storagedoc: remove accountAccessTier in doc since it's only for blob storagedoc: remove accountAccessTier in doc since it's only for blob storagedoc: remove accountAccessTier in doc since it's only for blob storage --- docs/driver-parameters.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/driver-parameters.md b/docs/driver-parameters.md index b4912cd719..f90437984a 100644 --- a/docs/driver-parameters.md +++ b/docs/driver-parameters.md @@ -17,7 +17,6 @@ shareName | specify Azure file share name | existing or new Azure file name | No shareNamePrefix | specify Azure file share name prefix created by driver | can only contain lowercase letters, numbers, hyphens, and length should be less than 21 | No | folderName | specify folder name in Azure file share | existing folder name in Azure file share | No | if folder name does not exist in file share, mount would fail shareAccessTier | [Access tier for file share](https://docs.microsoft.com/en-us/azure/storage/files/storage-files-planning#storage-tiers) | GpV2 account can choose between `TransactionOptimized` (default), `Hot`, and `Cool`. FileStorage account can choose `Premium` | No | empty(use default setting for different storage account types) -accountAccessTier | [Access tier for storage account](https://learn.microsoft.com/en-us/azure/storage/blobs/access-tiers-overview) | Standard account can choose `Hot` or `Cool`, and Premium account can only choose `Premium` | No | empty(use default setting for different storage account types) server | specify Azure storage account server address | existing server address, e.g. `accountname.privatelink.file.core.windows.net` | No | if empty, driver will use default `accountname.file.core.windows.net` or other sovereign cloud account address disableDeleteRetentionPolicy | specify whether disable DeleteRetentionPolicy for storage account created by driver | `true`,`false` | No | `false` allowBlobPublicAccess | Allow or disallow public access to all blobs or containers for storage account created by driver | `true`,`false` | No | `false` From 1336b31fa02bf53b7194b0654ae29523f88ce368 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Fri, 17 Feb 2023 13:51:39 +0000 Subject: [PATCH 028/109] fix: CVE-2022-41723 --- go.mod | 6 +- go.sum | 12 +- vendor/golang.org/x/net/html/parse.go | 2 +- vendor/golang.org/x/net/html/token.go | 49 +++- vendor/golang.org/x/net/http2/flow.go | 2 +- vendor/golang.org/x/net/http2/frame.go | 11 +- vendor/golang.org/x/net/http2/hpack/hpack.go | 81 ++++--- vendor/golang.org/x/net/http2/server.go | 20 +- vendor/golang.org/x/net/http2/transport.go | 2 +- vendor/golang.org/x/net/trace/histogram.go | 2 +- vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c | 1 + vendor/golang.org/x/sys/cpu/endian_big.go | 11 + vendor/golang.org/x/sys/cpu/endian_little.go | 11 + vendor/golang.org/x/sys/unix/gccgo_c.c | 4 +- .../golang.org/x/sys/unix/syscall_darwin.go | 1 + .../x/sys/unix/syscall_freebsd_386.go | 9 +- .../x/sys/unix/syscall_freebsd_amd64.go | 9 +- .../x/sys/unix/syscall_freebsd_arm.go | 9 +- .../x/sys/unix/syscall_freebsd_arm64.go | 9 +- .../x/sys/unix/syscall_freebsd_riscv64.go | 9 +- vendor/golang.org/x/sys/unix/syscall_linux.go | 3 +- vendor/golang.org/x/sys/unix/syscall_unix.go | 2 +- vendor/golang.org/x/sys/unix/timestruct.go | 2 +- vendor/golang.org/x/sys/unix/xattr_bsd.go | 9 +- vendor/golang.org/x/sys/unix/zerrors_linux.go | 30 ++- .../x/sys/unix/zerrors_linux_386.go | 1 + .../x/sys/unix/zerrors_linux_amd64.go | 1 + .../x/sys/unix/zerrors_linux_arm.go | 1 + .../x/sys/unix/zerrors_linux_arm64.go | 1 + .../x/sys/unix/zerrors_linux_loong64.go | 1 + .../x/sys/unix/zerrors_linux_mips.go | 1 + .../x/sys/unix/zerrors_linux_mips64.go | 1 + .../x/sys/unix/zerrors_linux_mips64le.go | 1 + .../x/sys/unix/zerrors_linux_mipsle.go | 1 + .../x/sys/unix/zerrors_linux_ppc.go | 1 + .../x/sys/unix/zerrors_linux_ppc64.go | 1 + .../x/sys/unix/zerrors_linux_ppc64le.go | 1 + .../x/sys/unix/zerrors_linux_riscv64.go | 1 + .../x/sys/unix/zerrors_linux_s390x.go | 1 + .../x/sys/unix/zerrors_linux_sparc64.go | 1 + .../golang.org/x/sys/unix/zsyscall_linux.go | 11 + vendor/golang.org/x/sys/unix/ztypes_linux.go | 217 +++++++++++++++--- .../x/sys/windows/syscall_windows.go | 14 +- vendor/modules.txt | 6 +- 44 files changed, 437 insertions(+), 132 deletions(-) create mode 100644 vendor/golang.org/x/sys/cpu/endian_big.go create mode 100644 vendor/golang.org/x/sys/cpu/endian_little.go diff --git a/go.mod b/go.mod index 795b7627fc..5e27d6a0a4 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/pelletier/go-toml v1.9.4 github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021 github.com/stretchr/testify v1.8.1 - golang.org/x/net v0.5.0 + golang.org/x/net v0.7.0 google.golang.org/grpc v1.49.0 google.golang.org/protobuf v1.28.1 k8s.io/api v0.26.0 @@ -114,8 +114,8 @@ require ( go.opentelemetry.io/proto/otlp v0.19.0 // indirect golang.org/x/crypto v0.5.0 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect - golang.org/x/sys v0.4.0 // indirect - golang.org/x/term v0.4.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/term v0.5.0 // indirect golang.org/x/text v0.7.0 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index a8dbef4d60..aa12d31a6e 100644 --- a/go.sum +++ b/go.sum @@ -551,8 +551,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -632,14 +632,14 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go index 291c91908d..46a89eda6c 100644 --- a/vendor/golang.org/x/net/html/parse.go +++ b/vendor/golang.org/x/net/html/parse.go @@ -184,7 +184,7 @@ func (p *parser) clearStackToContext(s scope) { } } -// parseGenericRawTextElements implements the generic raw text element parsing +// parseGenericRawTextElement implements the generic raw text element parsing // algorithm defined in 12.2.6.2. // https://html.spec.whatwg.org/multipage/parsing.html#parsing-elements-that-contain-only-text // TODO: Since both RAWTEXT and RCDATA states are treated as tokenizer's part diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go index ae24a6fdf4..50f7c6aac8 100644 --- a/vendor/golang.org/x/net/html/token.go +++ b/vendor/golang.org/x/net/html/token.go @@ -598,6 +598,11 @@ scriptDataDoubleEscapeEnd: // readComment reads the next comment token starting with "") return + } else if c == '-' { + dashCount = 1 + beginning = false + continue } } } @@ -645,6 +649,35 @@ func (z *Tokenizer) readComment() { } } +func (z *Tokenizer) calculateAbruptCommentDataEnd() int { + raw := z.Raw() + const prefixLen = len(""); err != nil { diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go index 50f7c6aac8..5c2a1f4efa 100644 --- a/vendor/golang.org/x/net/html/token.go +++ b/vendor/golang.org/x/net/html/token.go @@ -110,7 +110,7 @@ func (t Token) String() string { case SelfClosingTagToken: return "<" + t.tagString() + "/>" case CommentToken: - return "" + return "" case DoctypeToken: return "" } @@ -598,10 +598,10 @@ scriptDataDoubleEscapeEnd: // readComment reads the next comment token starting with " Ready -----> Stopped +// +// | ^ +// └---------------------------┘ +type ready struct { + state status // represent the state of the variable + generation int // represent the number of times we have transtioned to ready + lock sync.RWMutex // protect the state and generation variables + restartLock sync.Mutex // protect the transition from ready to pending where the channel is recreated + waitCh chan struct{} // blocks until is ready or stopped +} + +func newReady() *ready { + return &ready{ + waitCh: make(chan struct{}), + state: Pending, + } +} + +// done close the channel once the state is Ready or Stopped +func (r *ready) done() chan struct{} { + r.restartLock.Lock() + defer r.restartLock.Unlock() + return r.waitCh +} + +// wait blocks until it is Ready or Stopped, it returns an error if is Stopped. +func (r *ready) wait(ctx context.Context) error { + _, err := r.waitAndReadGeneration(ctx) + return err +} + +// waitAndReadGenration blocks until it is Ready or Stopped and returns number +// of times we entered ready state if Ready and error otherwise. +func (r *ready) waitAndReadGeneration(ctx context.Context) (int, error) { + for { + // r.done() only blocks if state is Pending + select { + case <-ctx.Done(): + return 0, ctx.Err() + case <-r.done(): + } + + r.lock.RLock() + switch r.state { + case Pending: + // since we allow to switch between the states Pending and Ready + // if there is a quick transition from Pending -> Ready -> Pending + // a process that was waiting can get unblocked and see a Pending + // state again. If the state is Pending we have to wait again to + // avoid an inconsistent state on the system, with some processes not + // waiting despite the state moved back to Pending. + r.lock.RUnlock() + case Ready: + generation := r.generation + r.lock.RUnlock() + return generation, nil + case Stopped: + r.lock.RUnlock() + return 0, fmt.Errorf("apiserver cacher is stopped") + default: + r.lock.RUnlock() + return 0, fmt.Errorf("unexpected apiserver cache state: %v", r.state) + } + } +} + +// check returns true only if it is Ready. +func (r *ready) check() bool { + _, ok := r.checkAndReadGeneration() + return ok +} + +// checkAndReadGeneration returns the current generation and whether it is Ready. +func (r *ready) checkAndReadGeneration() (int, bool) { + r.lock.RLock() + defer r.lock.RUnlock() + return r.generation, r.state == Ready +} + +// set the state to Pending (false) or Ready (true), it does not have effect if the state is Stopped. +func (r *ready) set(ok bool) { + r.lock.Lock() + defer r.lock.Unlock() + if r.state == Stopped { + return + } + if ok && r.state == Pending { + r.state = Ready + r.generation++ + select { + case <-r.waitCh: + default: + close(r.waitCh) + } + } else if !ok && r.state == Ready { + // creating the waitCh can be racy if + // something enter the wait() method + select { + case <-r.waitCh: + r.restartLock.Lock() + r.waitCh = make(chan struct{}) + r.restartLock.Unlock() + default: + } + r.state = Pending + } +} + +// stop the condition variable and set it as Stopped. This state is irreversible. +func (r *ready) stop() { + r.lock.Lock() + defer r.lock.Unlock() + if r.state != Stopped { + r.state = Stopped + } + select { + case <-r.waitCh: + default: + close(r.waitCh) + } +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/time_budget.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/time_budget.go new file mode 100644 index 0000000000..636c6ef8d6 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/time_budget.go @@ -0,0 +1,102 @@ +/* +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 cacher + +import ( + "sync" + "time" + + "k8s.io/utils/clock" +) + +const ( + refreshPerSecond = 50 * time.Millisecond + maxBudget = 100 * time.Millisecond +) + +// timeBudget implements a budget of time that you can use and is +// periodically being refreshed. The pattern to use it is: +// +// budget := newTimeBudget(...) +// ... +// timeout := budget.takeAvailable() +// // Now you can spend at most timeout on doing stuff +// ... +// // If you didn't use all timeout, return what you didn't use +// budget.returnUnused() +// +// NOTE: It's not recommended to be used concurrently from multiple threads - +// if first user takes the whole timeout, the second one will get 0 timeout +// even though the first one may return something later. +type timeBudget interface { + takeAvailable() time.Duration + returnUnused(unused time.Duration) +} + +type timeBudgetImpl struct { + sync.Mutex + clock clock.Clock + budget time.Duration + maxBudget time.Duration + refresh time.Duration + // last store last access time + last time.Time +} + +func newTimeBudget() timeBudget { + result := &timeBudgetImpl{ + clock: clock.RealClock{}, + budget: time.Duration(0), + refresh: refreshPerSecond, + maxBudget: maxBudget, + } + result.last = result.clock.Now() + return result +} + +func (t *timeBudgetImpl) takeAvailable() time.Duration { + t.Lock() + defer t.Unlock() + // budget accumulated since last access + now := t.clock.Now() + acc := now.Sub(t.last).Seconds() * t.refresh.Seconds() + if acc < 0 { + acc = 0 + } + // update current budget and store the current time + if t.budget = t.budget + time.Duration(acc*1e9); t.budget > t.maxBudget { + t.budget = t.maxBudget + } + t.last = now + result := t.budget + t.budget = time.Duration(0) + return result +} + +func (t *timeBudgetImpl) returnUnused(unused time.Duration) { + t.Lock() + defer t.Unlock() + if unused < 0 { + // We used more than allowed. + return + } + // add the unused time directly to the budget + // takeAvailable() will take into account the elapsed time + if t.budget = t.budget + unused; t.budget > t.maxBudget { + t.budget = t.maxBudget + } +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/util.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/util.go new file mode 100644 index 0000000000..7943a93dca --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/util.go @@ -0,0 +1,60 @@ +/* +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 cacher + +import ( + "strings" +) + +// hasPathPrefix returns true if the string matches pathPrefix exactly, or if is prefixed with pathPrefix at a path segment boundary +func hasPathPrefix(s, pathPrefix string) bool { + // Short circuit if s doesn't contain the prefix at all + if !strings.HasPrefix(s, pathPrefix) { + return false + } + + pathPrefixLength := len(pathPrefix) + + if len(s) == pathPrefixLength { + // Exact match + return true + } + if strings.HasSuffix(pathPrefix, "/") { + // pathPrefix already ensured a path segment boundary + return true + } + if s[pathPrefixLength:pathPrefixLength+1] == "/" { + // The next character in s is a path segment boundary + // Check this instead of normalizing pathPrefix to avoid allocating on every call + return true + } + return false +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go new file mode 100644 index 0000000000..4d86018e52 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go @@ -0,0 +1,725 @@ +/* +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 cacher + +import ( + "context" + "fmt" + "math" + "sort" + "sync" + "time" + + "k8s.io/apimachinery/pkg/api/errors" + "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/watch" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/cacher/metrics" + "k8s.io/client-go/tools/cache" + "k8s.io/component-base/tracing" + "k8s.io/klog/v2" + "k8s.io/utils/clock" +) + +const ( + // blockTimeout determines how long we're willing to block the request + // to wait for a given resource version to be propagated to cache, + // before terminating request and returning Timeout error with retry + // after suggestion. + blockTimeout = 3 * time.Second + + // resourceVersionTooHighRetrySeconds is the seconds before a operation should be retried by the client + // after receiving a 'too high resource version' error. + resourceVersionTooHighRetrySeconds = 1 + + // eventFreshDuration is time duration of events we want to keep. + // We set it to `defaultBookmarkFrequency` plus epsilon to maximize + // chances that last bookmark was sent within kept history, at the + // same time, minimizing the needed memory usage. + eventFreshDuration = 75 * time.Second + + // defaultLowerBoundCapacity is a default value for event cache capacity's lower bound. + // TODO: Figure out, to what value we can decreased it. + defaultLowerBoundCapacity = 100 + + // defaultUpperBoundCapacity should be able to keep eventFreshDuration of history. + defaultUpperBoundCapacity = 100 * 1024 +) + +// watchCacheEvent is a single "watch event" that is send to users of +// watchCache. Additionally to a typical "watch.Event" it contains +// the previous value of the object to enable proper filtering in the +// upper layers. +type watchCacheEvent struct { + Type watch.EventType + Object runtime.Object + ObjLabels labels.Set + ObjFields fields.Set + PrevObject runtime.Object + PrevObjLabels labels.Set + PrevObjFields fields.Set + Key string + ResourceVersion uint64 + RecordTime time.Time +} + +// Computing a key of an object is generally non-trivial (it performs +// e.g. validation underneath). Similarly computing object fields and +// labels. To avoid computing them multiple times (to serve the event +// in different List/Watch requests), in the underlying store we are +// keeping structs (key, object, labels, fields). +type storeElement struct { + Key string + Object runtime.Object + Labels labels.Set + Fields fields.Set +} + +func storeElementKey(obj interface{}) (string, error) { + elem, ok := obj.(*storeElement) + if !ok { + return "", fmt.Errorf("not a storeElement: %v", obj) + } + return elem.Key, nil +} + +func storeElementObject(obj interface{}) (runtime.Object, error) { + elem, ok := obj.(*storeElement) + if !ok { + return nil, fmt.Errorf("not a storeElement: %v", obj) + } + return elem.Object, nil +} + +func storeElementIndexFunc(objIndexFunc cache.IndexFunc) cache.IndexFunc { + return func(obj interface{}) (strings []string, e error) { + seo, err := storeElementObject(obj) + if err != nil { + return nil, err + } + return objIndexFunc(seo) + } +} + +func storeElementIndexers(indexers *cache.Indexers) cache.Indexers { + if indexers == nil { + return cache.Indexers{} + } + ret := cache.Indexers{} + for indexName, indexFunc := range *indexers { + ret[indexName] = storeElementIndexFunc(indexFunc) + } + return ret +} + +// watchCache implements a Store interface. +// However, it depends on the elements implementing runtime.Object interface. +// +// watchCache is a "sliding window" (with a limited capacity) of objects +// observed from a watch. +type watchCache struct { + sync.RWMutex + + // Condition on which lists are waiting for the fresh enough + // resource version. + cond *sync.Cond + + // Maximum size of history window. + capacity int + + // upper bound of capacity since event cache has a dynamic size. + upperBoundCapacity int + + // lower bound of capacity since event cache has a dynamic size. + lowerBoundCapacity int + + // keyFunc is used to get a key in the underlying storage for a given object. + keyFunc func(runtime.Object) (string, error) + + // getAttrsFunc is used to get labels and fields of an object. + getAttrsFunc func(runtime.Object) (labels.Set, fields.Set, error) + + // cache is used a cyclic buffer - the "current" contents of it are + // stored in [start_index%capacity, end_index%capacity) - so the + // "current" contents have exactly end_index-start_index items. + cache []*watchCacheEvent + startIndex int + endIndex int + // removedEventSinceRelist holds the information whether any of the events + // were already removed from the `cache` cyclic buffer since the last relist + removedEventSinceRelist bool + + // store will effectively support LIST operation from the "end of cache + // history" i.e. from the moment just after the newest cached watched event. + // It is necessary to effectively allow clients to start watching at now. + // NOTE: We assume that is thread-safe. + store cache.Indexer + + // ResourceVersion up to which the watchCache is propagated. + resourceVersion uint64 + + // ResourceVersion of the last list result (populated via Replace() method). + listResourceVersion uint64 + + // This handler is run at the end of every successful Replace() method. + onReplace func() + + // This handler is run at the end of every Add/Update/Delete method + // and additionally gets the previous value of the object. + eventHandler func(*watchCacheEvent) + + // for testing timeouts. + clock clock.Clock + + // An underlying storage.Versioner. + versioner storage.Versioner + + // cacher's group resource + groupResource schema.GroupResource + + // For testing cache interval invalidation. + indexValidator indexValidator +} + +func newWatchCache( + keyFunc func(runtime.Object) (string, error), + eventHandler func(*watchCacheEvent), + getAttrsFunc func(runtime.Object) (labels.Set, fields.Set, error), + versioner storage.Versioner, + indexers *cache.Indexers, + clock clock.Clock, + groupResource schema.GroupResource) *watchCache { + wc := &watchCache{ + capacity: defaultLowerBoundCapacity, + keyFunc: keyFunc, + getAttrsFunc: getAttrsFunc, + cache: make([]*watchCacheEvent, defaultLowerBoundCapacity), + lowerBoundCapacity: defaultLowerBoundCapacity, + upperBoundCapacity: defaultUpperBoundCapacity, + startIndex: 0, + endIndex: 0, + store: cache.NewIndexer(storeElementKey, storeElementIndexers(indexers)), + resourceVersion: 0, + listResourceVersion: 0, + eventHandler: eventHandler, + clock: clock, + versioner: versioner, + groupResource: groupResource, + } + metrics.WatchCacheCapacity.WithLabelValues(groupResource.String()).Set(float64(wc.capacity)) + wc.cond = sync.NewCond(wc.RLocker()) + wc.indexValidator = wc.isIndexValidLocked + + return wc +} + +// Add takes runtime.Object as an argument. +func (w *watchCache) Add(obj interface{}) error { + object, resourceVersion, err := w.objectToVersionedRuntimeObject(obj) + if err != nil { + return err + } + event := watch.Event{Type: watch.Added, Object: object} + + f := func(elem *storeElement) error { return w.store.Add(elem) } + return w.processEvent(event, resourceVersion, f) +} + +// Update takes runtime.Object as an argument. +func (w *watchCache) Update(obj interface{}) error { + object, resourceVersion, err := w.objectToVersionedRuntimeObject(obj) + if err != nil { + return err + } + event := watch.Event{Type: watch.Modified, Object: object} + + f := func(elem *storeElement) error { return w.store.Update(elem) } + return w.processEvent(event, resourceVersion, f) +} + +// Delete takes runtime.Object as an argument. +func (w *watchCache) Delete(obj interface{}) error { + object, resourceVersion, err := w.objectToVersionedRuntimeObject(obj) + if err != nil { + return err + } + event := watch.Event{Type: watch.Deleted, Object: object} + + f := func(elem *storeElement) error { return w.store.Delete(elem) } + return w.processEvent(event, resourceVersion, f) +} + +func (w *watchCache) objectToVersionedRuntimeObject(obj interface{}) (runtime.Object, uint64, error) { + object, ok := obj.(runtime.Object) + if !ok { + return nil, 0, fmt.Errorf("obj does not implement runtime.Object interface: %v", obj) + } + resourceVersion, err := w.versioner.ObjectResourceVersion(object) + if err != nil { + return nil, 0, err + } + return object, resourceVersion, nil +} + +// processEvent is safe as long as there is at most one call to it in flight +// at any point in time. +func (w *watchCache) processEvent(event watch.Event, resourceVersion uint64, updateFunc func(*storeElement) error) error { + metrics.EventsReceivedCounter.WithLabelValues(w.groupResource.String()).Inc() + + key, err := w.keyFunc(event.Object) + if err != nil { + return fmt.Errorf("couldn't compute key: %v", err) + } + elem := &storeElement{Key: key, Object: event.Object} + elem.Labels, elem.Fields, err = w.getAttrsFunc(event.Object) + if err != nil { + return err + } + + wcEvent := &watchCacheEvent{ + Type: event.Type, + Object: elem.Object, + ObjLabels: elem.Labels, + ObjFields: elem.Fields, + Key: key, + ResourceVersion: resourceVersion, + RecordTime: w.clock.Now(), + } + + if err := func() error { + // TODO: We should consider moving this lock below after the watchCacheEvent + // is created. In such situation, the only problematic scenario is Replace( + // happening after getting object from store and before acquiring a lock. + // Maybe introduce another lock for this purpose. + w.Lock() + defer w.Unlock() + + previous, exists, err := w.store.Get(elem) + if err != nil { + return err + } + if exists { + previousElem := previous.(*storeElement) + wcEvent.PrevObject = previousElem.Object + wcEvent.PrevObjLabels = previousElem.Labels + wcEvent.PrevObjFields = previousElem.Fields + } + + w.updateCache(wcEvent) + w.resourceVersion = resourceVersion + defer w.cond.Broadcast() + + return updateFunc(elem) + }(); err != nil { + return err + } + + // Avoid calling event handler under lock. + // This is safe as long as there is at most one call to Add/Update/Delete and + // UpdateResourceVersion in flight at any point in time, which is true now, + // because reflector calls them synchronously from its main thread. + if w.eventHandler != nil { + w.eventHandler(wcEvent) + } + return nil +} + +// Assumes that lock is already held for write. +func (w *watchCache) updateCache(event *watchCacheEvent) { + w.resizeCacheLocked(event.RecordTime) + if w.isCacheFullLocked() { + // Cache is full - remove the oldest element. + w.startIndex++ + w.removedEventSinceRelist = true + } + w.cache[w.endIndex%w.capacity] = event + w.endIndex++ +} + +// resizeCacheLocked resizes the cache if necessary: +// - increases capacity by 2x if cache is full and all cached events occurred within last eventFreshDuration. +// - decreases capacity by 2x when recent quarter of events occurred outside of eventFreshDuration(protect watchCache from flapping). +func (w *watchCache) resizeCacheLocked(eventTime time.Time) { + if w.isCacheFullLocked() && eventTime.Sub(w.cache[w.startIndex%w.capacity].RecordTime) < eventFreshDuration { + capacity := min(w.capacity*2, w.upperBoundCapacity) + if capacity > w.capacity { + w.doCacheResizeLocked(capacity) + } + return + } + if w.isCacheFullLocked() && eventTime.Sub(w.cache[(w.endIndex-w.capacity/4)%w.capacity].RecordTime) > eventFreshDuration { + capacity := max(w.capacity/2, w.lowerBoundCapacity) + if capacity < w.capacity { + w.doCacheResizeLocked(capacity) + } + return + } +} + +// isCacheFullLocked used to judge whether watchCacheEvent is full. +// Assumes that lock is already held for write. +func (w *watchCache) isCacheFullLocked() bool { + return w.endIndex == w.startIndex+w.capacity +} + +// doCacheResizeLocked resize watchCache's event array with different capacity. +// Assumes that lock is already held for write. +func (w *watchCache) doCacheResizeLocked(capacity int) { + newCache := make([]*watchCacheEvent, capacity) + if capacity < w.capacity { + // adjust startIndex if cache capacity shrink. + w.startIndex = w.endIndex - capacity + } + for i := w.startIndex; i < w.endIndex; i++ { + newCache[i%capacity] = w.cache[i%w.capacity] + } + w.cache = newCache + metrics.RecordsWatchCacheCapacityChange(w.groupResource.String(), w.capacity, capacity) + w.capacity = capacity +} + +func (w *watchCache) UpdateResourceVersion(resourceVersion string) { + rv, err := w.versioner.ParseResourceVersion(resourceVersion) + if err != nil { + klog.Errorf("Couldn't parse resourceVersion: %v", err) + return + } + + func() { + w.Lock() + defer w.Unlock() + w.resourceVersion = rv + }() + + // Avoid calling event handler under lock. + // This is safe as long as there is at most one call to Add/Update/Delete and + // UpdateResourceVersion in flight at any point in time, which is true now, + // because reflector calls them synchronously from its main thread. + if w.eventHandler != nil { + wcEvent := &watchCacheEvent{ + Type: watch.Bookmark, + ResourceVersion: rv, + } + w.eventHandler(wcEvent) + } +} + +// List returns list of pointers to objects. +func (w *watchCache) List() []interface{} { + return w.store.List() +} + +// waitUntilFreshAndBlock waits until cache is at least as fresh as given . +// NOTE: This function acquired lock and doesn't release it. +// You HAVE TO explicitly call w.RUnlock() after this function. +func (w *watchCache) waitUntilFreshAndBlock(ctx context.Context, resourceVersion uint64) error { + startTime := w.clock.Now() + + // In case resourceVersion is 0, we accept arbitrarily stale result. + // As a result, the condition in the below for loop will never be + // satisfied (w.resourceVersion is never negative), this call will + // never hit the w.cond.Wait(). + // As a result - we can optimize the code by not firing the wakeup + // function (and avoid starting a gorotuine), especially given that + // resourceVersion=0 is the most common case. + if resourceVersion > 0 { + go func() { + // Wake us up when the time limit has expired. The docs + // promise that time.After (well, NewTimer, which it calls) + // will wait *at least* the duration given. Since this go + // routine starts sometime after we record the start time, and + // it will wake up the loop below sometime after the broadcast, + // we don't need to worry about waking it up before the time + // has expired accidentally. + <-w.clock.After(blockTimeout) + w.cond.Broadcast() + }() + } + + w.RLock() + span := tracing.SpanFromContext(ctx) + span.AddEvent("watchCache locked acquired") + for w.resourceVersion < resourceVersion { + if w.clock.Since(startTime) >= blockTimeout { + // Request that the client retry after 'resourceVersionTooHighRetrySeconds' seconds. + return storage.NewTooLargeResourceVersionError(resourceVersion, w.resourceVersion, resourceVersionTooHighRetrySeconds) + } + w.cond.Wait() + } + span.AddEvent("watchCache fresh enough") + return nil +} + +type sortableStoreElements []interface{} + +func (s sortableStoreElements) Len() int { + return len(s) +} + +func (s sortableStoreElements) Less(i, j int) bool { + return s[i].(*storeElement).Key < s[j].(*storeElement).Key +} + +func (s sortableStoreElements) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +// WaitUntilFreshAndList returns list of pointers to `storeElement` objects along +// with their ResourceVersion and the name of the index, if any, that was used. +func (w *watchCache) WaitUntilFreshAndList(ctx context.Context, resourceVersion uint64, matchValues []storage.MatchValue) ([]interface{}, uint64, string, error) { + err := w.waitUntilFreshAndBlock(ctx, resourceVersion) + defer w.RUnlock() + if err != nil { + return nil, 0, "", err + } + + result, rv, index, err := func() ([]interface{}, uint64, string, error) { + // This isn't the place where we do "final filtering" - only some "prefiltering" is happening here. So the only + // requirement here is to NOT miss anything that should be returned. We can return as many non-matching items as we + // want - they will be filtered out later. The fact that we return less things is only further performance improvement. + // TODO: if multiple indexes match, return the one with the fewest items, so as to do as much filtering as possible. + for _, matchValue := range matchValues { + if result, err := w.store.ByIndex(matchValue.IndexName, matchValue.Value); err == nil { + return result, w.resourceVersion, matchValue.IndexName, nil + } + } + return w.store.List(), w.resourceVersion, "", nil + }() + + sort.Sort(sortableStoreElements(result)) + return result, rv, index, err +} + +// WaitUntilFreshAndGet returns a pointers to object. +func (w *watchCache) WaitUntilFreshAndGet(ctx context.Context, resourceVersion uint64, key string) (interface{}, bool, uint64, error) { + err := w.waitUntilFreshAndBlock(ctx, resourceVersion) + defer w.RUnlock() + if err != nil { + return nil, false, 0, err + } + value, exists, err := w.store.GetByKey(key) + return value, exists, w.resourceVersion, err +} + +func (w *watchCache) ListKeys() []string { + return w.store.ListKeys() +} + +// Get takes runtime.Object as a parameter. However, it returns +// pointer to . +func (w *watchCache) Get(obj interface{}) (interface{}, bool, error) { + object, ok := obj.(runtime.Object) + if !ok { + return nil, false, fmt.Errorf("obj does not implement runtime.Object interface: %v", obj) + } + key, err := w.keyFunc(object) + if err != nil { + return nil, false, fmt.Errorf("couldn't compute key: %v", err) + } + + return w.store.Get(&storeElement{Key: key, Object: object}) +} + +// GetByKey returns pointer to . +func (w *watchCache) GetByKey(key string) (interface{}, bool, error) { + return w.store.GetByKey(key) +} + +// Replace takes slice of runtime.Object as a parameter. +func (w *watchCache) Replace(objs []interface{}, resourceVersion string) error { + version, err := w.versioner.ParseResourceVersion(resourceVersion) + if err != nil { + return err + } + + toReplace := make([]interface{}, 0, len(objs)) + for _, obj := range objs { + object, ok := obj.(runtime.Object) + if !ok { + return fmt.Errorf("didn't get runtime.Object for replace: %#v", obj) + } + key, err := w.keyFunc(object) + if err != nil { + return fmt.Errorf("couldn't compute key: %v", err) + } + objLabels, objFields, err := w.getAttrsFunc(object) + if err != nil { + return err + } + toReplace = append(toReplace, &storeElement{ + Key: key, + Object: object, + Labels: objLabels, + Fields: objFields, + }) + } + + w.Lock() + defer w.Unlock() + + // Ensure startIndex never decreases, so that existing watchCacheInterval + // instances get "invalid" errors if the try to download from the buffer + // using their own start/end indexes calculated from previous buffer + // content. + + // Empty the cyclic buffer, ensuring startIndex doesn't decrease. + w.startIndex = w.endIndex + w.removedEventSinceRelist = false + + if err := w.store.Replace(toReplace, resourceVersion); err != nil { + return err + } + w.listResourceVersion = version + w.resourceVersion = version + if w.onReplace != nil { + w.onReplace() + } + w.cond.Broadcast() + klog.V(3).Infof("Replace watchCache (rev: %v) ", resourceVersion) + return nil +} + +func (w *watchCache) SetOnReplace(onReplace func()) { + w.Lock() + defer w.Unlock() + w.onReplace = onReplace +} + +func (w *watchCache) Resync() error { + // Nothing to do + return nil +} + +func (w *watchCache) currentCapacity() int { + w.Lock() + defer w.Unlock() + return w.capacity +} + +const ( + // minWatchChanSize is the min size of channels used by the watch. + // We keep that set to 10 for "backward compatibility" until we + // convince ourselves based on some metrics that decreasing is safe. + minWatchChanSize = 10 + // maxWatchChanSizeWithIndexAndTriger is the max size of the channel + // used by the watch using the index and trigger selector. + maxWatchChanSizeWithIndexAndTrigger = 10 + // maxWatchChanSizeWithIndexWithoutTrigger is the max size of the channel + // used by the watch using the index but without triggering selector. + // We keep that set to 1000 for "backward compatibility", until we + // convinced ourselves based on some metrics that decreasing is safe. + maxWatchChanSizeWithIndexWithoutTrigger = 1000 + // maxWatchChanSizeWithoutIndex is the max size of the channel + // used by the watch not using the index. + // TODO(wojtek-t): Figure out if the value shouldn't be higher. + maxWatchChanSizeWithoutIndex = 100 +) + +func (w *watchCache) suggestedWatchChannelSize(indexExists, triggerUsed bool) int { + // To estimate the channel size we use a heuristic that a channel + // should roughly be able to keep one second of history. + // We don't have an exact data, but given we store updates from + // the last , we approach it by dividing the + // capacity by the length of the history window. + chanSize := int(math.Ceil(float64(w.currentCapacity()) / eventFreshDuration.Seconds())) + + // Finally we adjust the size to avoid ending with too low or + // to large values. + if chanSize < minWatchChanSize { + chanSize = minWatchChanSize + } + var maxChanSize int + switch { + case indexExists && triggerUsed: + maxChanSize = maxWatchChanSizeWithIndexAndTrigger + case indexExists && !triggerUsed: + maxChanSize = maxWatchChanSizeWithIndexWithoutTrigger + case !indexExists: + maxChanSize = maxWatchChanSizeWithoutIndex + } + if chanSize > maxChanSize { + chanSize = maxChanSize + } + return chanSize +} + +// isIndexValidLocked checks if a given index is still valid. +// This assumes that the lock is held. +func (w *watchCache) isIndexValidLocked(index int) bool { + return index >= w.startIndex +} + +// getAllEventsSinceLocked returns a watchCacheInterval that can be used to +// retrieve events since a certain resourceVersion. This function assumes to +// be called under the watchCache lock. +func (w *watchCache) getAllEventsSinceLocked(resourceVersion uint64) (*watchCacheInterval, error) { + size := w.endIndex - w.startIndex + var oldest uint64 + switch { + case w.listResourceVersion > 0 && !w.removedEventSinceRelist: + // If no event was removed from the buffer since last relist, the oldest watch + // event we can deliver is one greater than the resource version of the list. + oldest = w.listResourceVersion + 1 + case size > 0: + // If the previous condition is not satisfied: either some event was already + // removed from the buffer or we've never completed a list (the latter can + // only happen in unit tests that populate the buffer without performing + // list/replace operations), the oldest watch event we can deliver is the first + // one in the buffer. + oldest = w.cache[w.startIndex%w.capacity].ResourceVersion + default: + return nil, fmt.Errorf("watch cache isn't correctly initialized") + } + + if resourceVersion == 0 { + // resourceVersion = 0 means that we don't require any specific starting point + // and we would like to start watching from ~now. + // However, to keep backward compatibility, we additionally need to return the + // current state and only then start watching from that point. + // + // TODO: In v2 api, we should stop returning the current state - #13969. + return w.getIntervalFromStoreLocked() + } + if resourceVersion < oldest-1 { + return nil, errors.NewResourceExpired(fmt.Sprintf("too old resource version: %d (%d)", resourceVersion, oldest-1)) + } + + // Binary search the smallest index at which resourceVersion is greater than the given one. + f := func(i int) bool { + return w.cache[(w.startIndex+i)%w.capacity].ResourceVersion > resourceVersion + } + first := sort.Search(size, f) + indexerFunc := func(i int) *watchCacheEvent { + return w.cache[i%w.capacity] + } + ci := newCacheInterval(w.startIndex+first, w.endIndex, indexerFunc, w.indexValidator, &w.RWMutex) + return ci, nil +} + +// getIntervalFromStoreLocked returns a watchCacheInterval +// that covers the entire storage state. +// This function assumes to be called under the watchCache lock. +func (w *watchCache) getIntervalFromStoreLocked() (*watchCacheInterval, error) { + ci, err := newCacheIntervalFromStore(w.resourceVersion, w.store, w.getAttrsFunc) + if err != nil { + return nil, err + } + return ci, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache_interval.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache_interval.go new file mode 100644 index 0000000000..c455357e04 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache_interval.go @@ -0,0 +1,226 @@ +/* +Copyright 2021 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 cacher + +import ( + "fmt" + "sync" + + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +// watchCacheInterval serves as an abstraction over a source +// of watchCacheEvents. It maintains a window of events over +// an underlying source and these events can be served using +// the exposed Next() API. The main intent for doing things +// this way is to introduce an upper bound of memory usage +// for starting a watch and reduce the maximum possible time +// interval for which the lock would be held while events are +// copied over. +// +// The source of events for the interval is typically either +// the watchCache circular buffer, if events being retrieved +// need to be for resource versions > 0 or the underlying +// implementation of Store, if resource version = 0. +// +// Furthermore, an interval can be either valid or invalid at +// any given point of time. The notion of validity makes sense +// only in cases where the window of events in the underlying +// source can change over time - i.e. for watchCache circular +// buffer. When the circular buffer is full and an event needs +// to be popped off, watchCache::startIndex is incremented. In +// this case, an interval tracking that popped event is valid +// only if it has already been copied to its internal buffer. +// However, for efficiency we perform that lazily and we mark +// an interval as invalid iff we need to copy events from the +// watchCache and we end up needing events that have already +// been popped off. This translates to the following condition: +// +// watchCacheInterval::startIndex >= watchCache::startIndex. +// +// When this condition becomes false, the interval is no longer +// valid and should not be used to retrieve and serve elements +// from the underlying source. +type watchCacheInterval struct { + // startIndex denotes the starting point of the interval + // being considered. The value is the index in the actual + // source of watchCacheEvents. If the source of events is + // the watchCache, then this must be used modulo capacity. + startIndex int + + // endIndex denotes the ending point of the interval being + // considered. The value is the index in the actual source + // of events. If the source of the events is the watchCache, + // then this should be used modulo capacity. + endIndex int + + // indexer is meant to inject behaviour for how an event must + // be retrieved from the underlying source given an index. + indexer indexerFunc + + // indexValidator is used to check if a given index is still + // valid perspective. If it is deemed that the index is not + // valid, then this interval can no longer be used to serve + // events. Use of indexValidator is warranted only in cases + // where the window of events in the underlying source can + // change over time. Furthermore, an interval is invalid if + // its startIndex no longer coincides with the startIndex of + // underlying source. + indexValidator indexValidator + + // buffer holds watchCacheEvents that this interval returns on + // a call to Next(). This exists mainly to reduce acquiring the + // lock on each invocation of Next(). + buffer *watchCacheIntervalBuffer + + // lock effectively protects access to the underlying source + // of events through - indexer and indexValidator. + // + // Given that indexer and indexValidator only read state, if + // possible, Locker obtained through RLocker() is provided. + lock sync.Locker +} + +type attrFunc func(runtime.Object) (labels.Set, fields.Set, error) +type indexerFunc func(int) *watchCacheEvent +type indexValidator func(int) bool + +func newCacheInterval(startIndex, endIndex int, indexer indexerFunc, indexValidator indexValidator, locker sync.Locker) *watchCacheInterval { + return &watchCacheInterval{ + startIndex: startIndex, + endIndex: endIndex, + indexer: indexer, + indexValidator: indexValidator, + buffer: &watchCacheIntervalBuffer{buffer: make([]*watchCacheEvent, bufferSize)}, + lock: locker, + } +} + +// newCacheIntervalFromStore is meant to handle the case of rv=0, such that the events +// returned by Next() need to be events from a List() done on the underlying store of +// the watch cache. +func newCacheIntervalFromStore(resourceVersion uint64, store cache.Indexer, getAttrsFunc attrFunc) (*watchCacheInterval, error) { + buffer := &watchCacheIntervalBuffer{} + allItems := store.List() + buffer.buffer = make([]*watchCacheEvent, len(allItems)) + for i, item := range allItems { + elem, ok := item.(*storeElement) + if !ok { + return nil, fmt.Errorf("not a storeElement: %v", elem) + } + objLabels, objFields, err := getAttrsFunc(elem.Object) + if err != nil { + return nil, err + } + buffer.buffer[i] = &watchCacheEvent{ + Type: watch.Added, + Object: elem.Object, + ObjLabels: objLabels, + ObjFields: objFields, + Key: elem.Key, + ResourceVersion: resourceVersion, + } + buffer.endIndex++ + } + ci := &watchCacheInterval{ + startIndex: 0, + // Simulate that we already have all the events we're looking for. + endIndex: 0, + buffer: buffer, + } + + return ci, nil +} + +// Next returns the next item in the cache interval provided the cache +// interval is still valid. An error is returned if the interval is +// invalidated. +func (wci *watchCacheInterval) Next() (*watchCacheEvent, error) { + // if there are items in the buffer to return, return from + // the buffer. + if event, exists := wci.buffer.next(); exists { + return event, nil + } + // check if there are still other events in this interval + // that can be processed. + if wci.startIndex >= wci.endIndex { + return nil, nil + } + wci.lock.Lock() + defer wci.lock.Unlock() + + if valid := wci.indexValidator(wci.startIndex); !valid { + return nil, fmt.Errorf("cache interval invalidated, interval startIndex: %d", wci.startIndex) + } + + wci.fillBuffer() + if event, exists := wci.buffer.next(); exists { + return event, nil + } + return nil, nil +} + +func (wci *watchCacheInterval) fillBuffer() { + wci.buffer.startIndex = 0 + wci.buffer.endIndex = 0 + for wci.startIndex < wci.endIndex && !wci.buffer.isFull() { + event := wci.indexer(wci.startIndex) + if event == nil { + break + } + wci.buffer.buffer[wci.buffer.endIndex] = event + wci.buffer.endIndex++ + wci.startIndex++ + } +} + +const bufferSize = 100 + +// watchCacheIntervalBuffer is used to reduce acquiring +// the lock on each invocation of watchCacheInterval.Next(). +type watchCacheIntervalBuffer struct { + // buffer is used to hold watchCacheEvents that + // the interval returns on a call to Next(). + buffer []*watchCacheEvent + // The first element of buffer is defined by startIndex, + // its last element is defined by endIndex. + startIndex int + endIndex int +} + +// next returns the next event present in the interval buffer provided +// it is not empty. +func (wcib *watchCacheIntervalBuffer) next() (*watchCacheEvent, bool) { + if wcib.isEmpty() { + return nil, false + } + next := wcib.buffer[wcib.startIndex] + wcib.startIndex++ + return next, true +} + +func (wcib *watchCacheIntervalBuffer) isFull() bool { + return wcib.endIndex >= bufferSize +} + +func (wcib *watchCacheIntervalBuffer) isEmpty() bool { + return wcib.startIndex == wcib.endIndex +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/continue.go b/vendor/k8s.io/apiserver/pkg/storage/continue.go new file mode 100644 index 0000000000..fcd95af9b3 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/continue.go @@ -0,0 +1,93 @@ +/* +Copyright 2022 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 ( + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "path" + "strings" +) + +var ( + ErrInvalidStartRV = errors.New("continue key is not valid: incorrect encoded start resourceVersion (version meta.k8s.io/v1)") + ErrEmptyStartKey = errors.New("continue key is not valid: encoded start key empty (version meta.k8s.io/v1)") + ErrGenericInvalidKey = errors.New("continue key is not valid") + ErrUnrecognizedEncodedVersion = errors.New("continue key is not valid: server does not recognize this encoded version") +) + +// continueToken is a simple structured object for encoding the state of a continue token. +// TODO: if we change the version of the encoded from, we can't start encoding the new version +// until all other servers are upgraded (i.e. we need to support rolling schema) +// This is a public API struct and cannot change. +type continueToken struct { + APIVersion string `json:"v"` + ResourceVersion int64 `json:"rv"` + StartKey string `json:"start"` +} + +// DecodeContinue transforms an encoded predicate from into a versioned struct. +// TODO: return a typed error that instructs clients that they must relist +func DecodeContinue(continueValue, keyPrefix string) (fromKey string, rv int64, err error) { + data, err := base64.RawURLEncoding.DecodeString(continueValue) + if err != nil { + return "", 0, fmt.Errorf("%w: %v", ErrGenericInvalidKey, err) + } + var c continueToken + if err := json.Unmarshal(data, &c); err != nil { + return "", 0, fmt.Errorf("%w: %v", ErrGenericInvalidKey, err) + } + switch c.APIVersion { + case "meta.k8s.io/v1": + if c.ResourceVersion == 0 { + return "", 0, ErrInvalidStartRV + } + if len(c.StartKey) == 0 { + return "", 0, ErrEmptyStartKey + } + // defend against path traversal attacks by clients - path.Clean will ensure that startKey cannot + // be at a higher level of the hierarchy, and so when we append the key prefix we will end up with + // continue start key that is fully qualified and cannot range over anything less specific than + // keyPrefix. + key := c.StartKey + if !strings.HasPrefix(key, "/") { + key = "/" + key + } + cleaned := path.Clean(key) + if cleaned != key { + return "", 0, fmt.Errorf("%w: %v", ErrGenericInvalidKey, c.StartKey) + } + return keyPrefix + cleaned[1:], c.ResourceVersion, nil + default: + return "", 0, fmt.Errorf("%w %v", ErrUnrecognizedEncodedVersion, c.APIVersion) + } +} + +// EncodeContinue returns a string representing the encoded continuation of the current query. +func EncodeContinue(key, keyPrefix string, resourceVersion int64) (string, error) { + nextKey := strings.TrimPrefix(key, keyPrefix) + if nextKey == key { + return "", fmt.Errorf("unable to encode next field: the key and key prefix do not match") + } + out, err := json.Marshal(&continueToken{APIVersion: "meta.k8s.io/v1", ResourceVersion: resourceVersion, StartKey: nextKey}) + if err != nil { + return "", err + } + return base64.RawURLEncoding.EncodeToString(out), nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/doc.go b/vendor/k8s.io/apiserver/pkg/storage/doc.go new file mode 100644 index 0000000000..fbdd944687 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/doc.go @@ -0,0 +1,18 @@ +/* +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. +*/ + +// Interfaces for database-related operations. +package storage // import "k8s.io/apiserver/pkg/storage" diff --git a/vendor/k8s.io/apiserver/pkg/storage/errors.go b/vendor/k8s.io/apiserver/pkg/storage/errors.go new file mode 100644 index 0000000000..ed4f4d0d0e --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/errors.go @@ -0,0 +1,195 @@ +/* +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 storage + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +const ( + ErrCodeKeyNotFound int = iota + 1 + ErrCodeKeyExists + ErrCodeResourceVersionConflicts + ErrCodeInvalidObj + ErrCodeUnreachable +) + +var errCodeToMessage = map[int]string{ + ErrCodeKeyNotFound: "key not found", + ErrCodeKeyExists: "key exists", + ErrCodeResourceVersionConflicts: "resource version conflicts", + ErrCodeInvalidObj: "invalid object", + ErrCodeUnreachable: "server unreachable", +} + +func NewKeyNotFoundError(key string, rv int64) *StorageError { + return &StorageError{ + Code: ErrCodeKeyNotFound, + Key: key, + ResourceVersion: rv, + } +} + +func NewKeyExistsError(key string, rv int64) *StorageError { + return &StorageError{ + Code: ErrCodeKeyExists, + Key: key, + ResourceVersion: rv, + } +} + +func NewResourceVersionConflictsError(key string, rv int64) *StorageError { + return &StorageError{ + Code: ErrCodeResourceVersionConflicts, + Key: key, + ResourceVersion: rv, + } +} + +func NewUnreachableError(key string, rv int64) *StorageError { + return &StorageError{ + Code: ErrCodeUnreachable, + Key: key, + ResourceVersion: rv, + } +} + +func NewInvalidObjError(key, msg string) *StorageError { + return &StorageError{ + Code: ErrCodeInvalidObj, + Key: key, + AdditionalErrorMsg: msg, + } +} + +type StorageError struct { + Code int + Key string + ResourceVersion int64 + AdditionalErrorMsg string +} + +func (e *StorageError) Error() string { + return fmt.Sprintf("StorageError: %s, Code: %d, Key: %s, ResourceVersion: %d, AdditionalErrorMsg: %s", + errCodeToMessage[e.Code], e.Code, e.Key, e.ResourceVersion, e.AdditionalErrorMsg) +} + +// IsNotFound returns true if and only if err is "key" not found error. +func IsNotFound(err error) bool { + return isErrCode(err, ErrCodeKeyNotFound) +} + +// IsExist returns true if and only if err is "key" already exists error. +func IsExist(err error) bool { + return isErrCode(err, ErrCodeKeyExists) +} + +// IsUnreachable returns true if and only if err indicates the server could not be reached. +func IsUnreachable(err error) bool { + return isErrCode(err, ErrCodeUnreachable) +} + +// IsConflict returns true if and only if err is a write conflict. +func IsConflict(err error) bool { + return isErrCode(err, ErrCodeResourceVersionConflicts) +} + +// IsInvalidObj returns true if and only if err is invalid error +func IsInvalidObj(err error) bool { + return isErrCode(err, ErrCodeInvalidObj) +} + +func isErrCode(err error, code int) bool { + if err == nil { + return false + } + if e, ok := err.(*StorageError); ok { + return e.Code == code + } + return false +} + +// InvalidError is generated when an error caused by invalid API object occurs +// in the storage package. +type InvalidError struct { + Errs field.ErrorList +} + +func (e InvalidError) Error() string { + return e.Errs.ToAggregate().Error() +} + +// IsInvalidError returns true if and only if err is an InvalidError. +func IsInvalidError(err error) bool { + _, ok := err.(InvalidError) + return ok +} + +func NewInvalidError(errors field.ErrorList) InvalidError { + return InvalidError{errors} +} + +// InternalError is generated when an error occurs in the storage package, i.e., +// not from the underlying storage backend (e.g., etcd). +type InternalError struct { + Reason string +} + +func (e InternalError) Error() string { + return e.Reason +} + +// IsInternalError returns true if and only if err is an InternalError. +func IsInternalError(err error) bool { + _, ok := err.(InternalError) + return ok +} + +func NewInternalError(reason string) InternalError { + return InternalError{reason} +} + +func NewInternalErrorf(format string, a ...interface{}) InternalError { + return InternalError{fmt.Sprintf(format, a...)} +} + +var tooLargeResourceVersionCauseMsg = "Too large resource version" + +// NewTooLargeResourceVersionError returns a timeout error with the given retrySeconds for a request for +// a minimum resource version that is larger than the largest currently available resource version for a requested resource. +func NewTooLargeResourceVersionError(minimumResourceVersion, currentRevision uint64, retrySeconds int) error { + err := errors.NewTimeoutError(fmt.Sprintf("Too large resource version: %d, current: %d", minimumResourceVersion, currentRevision), retrySeconds) + err.ErrStatus.Details.Causes = []metav1.StatusCause{ + { + Type: metav1.CauseTypeResourceVersionTooLarge, + Message: tooLargeResourceVersionCauseMsg, + }, + } + return err +} + +// IsTooLargeResourceVersion returns true if the error is a TooLargeResourceVersion error. +func IsTooLargeResourceVersion(err error) bool { + if !errors.IsTimeout(err) { + return false + } + return errors.HasStatusCause(err, metav1.CauseTypeResourceVersionTooLarge) +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/errors/doc.go b/vendor/k8s.io/apiserver/pkg/storage/errors/doc.go new file mode 100644 index 0000000000..e251b61680 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/errors/doc.go @@ -0,0 +1,18 @@ +/* +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 storage provides conversion of storage errors to API errors. +package storage // import "k8s.io/apiserver/pkg/storage/errors" diff --git a/vendor/k8s.io/apiserver/pkg/storage/errors/storage.go b/vendor/k8s.io/apiserver/pkg/storage/errors/storage.go new file mode 100644 index 0000000000..89f3453980 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/errors/storage.go @@ -0,0 +1,116 @@ +/* +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 storage + +import ( + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/storage" +) + +// InterpretListError converts a generic error on a retrieval +// operation into the appropriate API error. +func InterpretListError(err error, qualifiedResource schema.GroupResource) error { + switch { + case storage.IsNotFound(err): + return errors.NewNotFound(qualifiedResource, "") + case storage.IsUnreachable(err): + return errors.NewServerTimeout(qualifiedResource, "list", 2) // TODO: make configurable or handled at a higher level + case storage.IsInternalError(err): + return errors.NewInternalError(err) + default: + return err + } +} + +// InterpretGetError converts a generic error on a retrieval +// operation into the appropriate API error. +func InterpretGetError(err error, qualifiedResource schema.GroupResource, name string) error { + switch { + case storage.IsNotFound(err): + return errors.NewNotFound(qualifiedResource, name) + case storage.IsUnreachable(err): + return errors.NewServerTimeout(qualifiedResource, "get", 2) // TODO: make configurable or handled at a higher level + case storage.IsInternalError(err): + return errors.NewInternalError(err) + default: + return err + } +} + +// InterpretCreateError converts a generic error on a create +// operation into the appropriate API error. +func InterpretCreateError(err error, qualifiedResource schema.GroupResource, name string) error { + switch { + case storage.IsExist(err): + return errors.NewAlreadyExists(qualifiedResource, name) + case storage.IsUnreachable(err): + return errors.NewServerTimeout(qualifiedResource, "create", 2) // TODO: make configurable or handled at a higher level + case storage.IsInternalError(err): + return errors.NewInternalError(err) + default: + return err + } +} + +// InterpretUpdateError converts a generic error on an update +// operation into the appropriate API error. +func InterpretUpdateError(err error, qualifiedResource schema.GroupResource, name string) error { + switch { + case storage.IsConflict(err), storage.IsExist(err), storage.IsInvalidObj(err): + return errors.NewConflict(qualifiedResource, name, err) + case storage.IsUnreachable(err): + return errors.NewServerTimeout(qualifiedResource, "update", 2) // TODO: make configurable or handled at a higher level + case storage.IsNotFound(err): + return errors.NewNotFound(qualifiedResource, name) + case storage.IsInternalError(err): + return errors.NewInternalError(err) + default: + return err + } +} + +// InterpretDeleteError converts a generic error on a delete +// operation into the appropriate API error. +func InterpretDeleteError(err error, qualifiedResource schema.GroupResource, name string) error { + switch { + case storage.IsNotFound(err): + return errors.NewNotFound(qualifiedResource, name) + case storage.IsUnreachable(err): + return errors.NewServerTimeout(qualifiedResource, "delete", 2) // TODO: make configurable or handled at a higher level + case storage.IsConflict(err), storage.IsExist(err), storage.IsInvalidObj(err): + return errors.NewConflict(qualifiedResource, name, err) + case storage.IsInternalError(err): + return errors.NewInternalError(err) + default: + return err + } +} + +// InterpretWatchError converts a generic error on a watch +// operation into the appropriate API error. +func InterpretWatchError(err error, resource schema.GroupResource, name string) error { + switch { + case storage.IsInvalidError(err): + invalidError, _ := err.(storage.InvalidError) + return errors.NewInvalid(schema.GroupKind{Group: resource.Group, Kind: resource.Resource}, name, invalidError.Errs) + case storage.IsInternalError(err): + return errors.NewInternalError(err) + default: + return err + } +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/OWNERS b/vendor/k8s.io/apiserver/pkg/storage/etcd3/OWNERS new file mode 100644 index 0000000000..6b7e2928ea --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/OWNERS @@ -0,0 +1,4 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +reviewers: + - wojtek-t diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/compact.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/compact.go new file mode 100644 index 0000000000..f279c6cabb --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/compact.go @@ -0,0 +1,162 @@ +/* +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 etcd3 + +import ( + "context" + "strconv" + "sync" + "time" + + clientv3 "go.etcd.io/etcd/client/v3" + "k8s.io/klog/v2" +) + +const ( + compactRevKey = "compact_rev_key" +) + +var ( + endpointsMapMu sync.Mutex + endpointsMap map[string]struct{} +) + +func init() { + endpointsMap = make(map[string]struct{}) +} + +// StartCompactor starts a compactor in the background to compact old version of keys that's not needed. +// By default, we save the most recent 5 minutes data and compact versions > 5minutes ago. +// It should be enough for slow watchers and to tolerate burst. +// TODO: We might keep a longer history (12h) in the future once storage API can take advantage of past version of keys. +func StartCompactor(ctx context.Context, client *clientv3.Client, compactInterval time.Duration) { + endpointsMapMu.Lock() + defer endpointsMapMu.Unlock() + + // In one process, we can have only one compactor for one cluster. + // Currently we rely on endpoints to differentiate clusters. + for _, ep := range client.Endpoints() { + if _, ok := endpointsMap[ep]; ok { + klog.V(4).Infof("compactor already exists for endpoints %v", client.Endpoints()) + return + } + } + for _, ep := range client.Endpoints() { + endpointsMap[ep] = struct{}{} + } + + if compactInterval != 0 { + go compactor(ctx, client, compactInterval) + } +} + +// compactor periodically compacts historical versions of keys in etcd. +// It will compact keys with versions older than given interval. +// In other words, after compaction, it will only contain keys set during last interval. +// Any API call for the older versions of keys will return error. +// Interval is the time interval between each compaction. The first compaction happens after "interval". +func compactor(ctx context.Context, client *clientv3.Client, interval time.Duration) { + // Technical definitions: + // We have a special key in etcd defined as *compactRevKey*. + // compactRevKey's value will be set to the string of last compacted revision. + // compactRevKey's version will be used as logical time for comparison. THe version is referred as compact time. + // Initially, because the key doesn't exist, the compact time (version) is 0. + // + // Algorithm: + // - Compare to see if (local compact_time) = (remote compact_time). + // - If yes, increment both local and remote compact_time, and do a compaction. + // - If not, set local to remote compact_time. + // + // Technical details/insights: + // + // The protocol here is lease based. If one compactor CAS successfully, the others would know it when they fail in + // CAS later and would try again in 5 minutes. If an APIServer crashed, another one would "take over" the lease. + // + // For example, in the following diagram, we have a compactor C1 doing compaction in t1, t2. Another compactor C2 + // at t1' (t1 < t1' < t2) would CAS fail, set its known oldRev to rev at t1', and try again in t2' (t2' > t2). + // If C1 crashed and wouldn't compact at t2, C2 would CAS successfully at t2'. + // + // oldRev(t2) curRev(t2) + // + + // oldRev curRev | + // + + | + // | | | + // | | t1' | t2' + // +---v-------------v----^---------v------^----> + // t0 t1 t2 + // + // We have the guarantees: + // - in normal cases, the interval is 5 minutes. + // - in failover, the interval is >5m and <10m + // + // FAQ: + // - What if time is not accurate? We don't care as long as someone did the compaction. Atomicity is ensured using + // etcd API. + // - What happened under heavy load scenarios? Initially, each apiserver will do only one compaction + // every 5 minutes. This is very unlikely affecting or affected w.r.t. server load. + + var compactTime int64 + var rev int64 + var err error + for { + select { + case <-time.After(interval): + case <-ctx.Done(): + return + } + + compactTime, rev, err = compact(ctx, client, compactTime, rev) + if err != nil { + klog.Errorf("etcd: endpoint (%v) compact failed: %v", client.Endpoints(), err) + continue + } + } +} + +// compact compacts etcd store and returns current rev. +// It will return the current compact time and global revision if no error occurred. +// Note that CAS fail will not incur any error. +func compact(ctx context.Context, client *clientv3.Client, t, rev int64) (int64, int64, error) { + resp, err := client.KV.Txn(ctx).If( + clientv3.Compare(clientv3.Version(compactRevKey), "=", t), + ).Then( + clientv3.OpPut(compactRevKey, strconv.FormatInt(rev, 10)), // Expect side effect: increment Version + ).Else( + clientv3.OpGet(compactRevKey), + ).Commit() + if err != nil { + return t, rev, err + } + + curRev := resp.Header.Revision + + if !resp.Succeeded { + curTime := resp.Responses[0].GetResponseRange().Kvs[0].Version + return curTime, curRev, nil + } + curTime := t + 1 + + if rev == 0 { + // We don't compact on bootstrap. + return curTime, curRev, nil + } + if _, err = client.Compact(ctx, rev); err != nil { + return curTime, curRev, err + } + klog.V(4).Infof("etcd: compacted rev (%d), endpoints (%v)", rev, client.Endpoints()) + return curTime, curRev, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/errors.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/errors.go new file mode 100644 index 0000000000..d71c9917dc --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/errors.go @@ -0,0 +1,72 @@ +/* +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 etcd3 + +import ( + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apiserver/pkg/storage" + + etcdrpc "go.etcd.io/etcd/api/v3/v3rpc/rpctypes" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +func interpretWatchError(err error) error { + switch { + case err == etcdrpc.ErrCompacted: + return errors.NewResourceExpired("The resourceVersion for the provided watch is too old.") + } + return err +} + +const ( + expired string = "The resourceVersion for the provided list is too old." + continueExpired string = "The provided continue parameter is too old " + + "to display a consistent list result. You can start a new list without " + + "the continue parameter." + inconsistentContinue string = "The provided continue parameter is too old " + + "to display a consistent list result. You can start a new list without " + + "the continue parameter, or use the continue token in this response to " + + "retrieve the remainder of the results. Continuing with the provided " + + "token results in an inconsistent list - objects that were created, " + + "modified, or deleted between the time the first chunk was returned " + + "and now may show up in the list." +) + +func interpretListError(err error, paging bool, continueKey, keyPrefix string) error { + switch { + case err == etcdrpc.ErrCompacted: + if paging { + return handleCompactedErrorForPaging(continueKey, keyPrefix) + } + return errors.NewResourceExpired(expired) + } + return err +} + +func handleCompactedErrorForPaging(continueKey, keyPrefix string) error { + // continueToken.ResoureVersion=-1 means that the apiserver can + // continue the list at the latest resource version. We don't use rv=0 + // for this purpose to distinguish from a bad token that has empty rv. + newToken, err := storage.EncodeContinue(continueKey, keyPrefix, -1) + if err != nil { + utilruntime.HandleError(err) + return errors.NewResourceExpired(continueExpired) + } + statusError := errors.NewResourceExpired(inconsistentContinue) + statusError.ErrStatus.ListMeta.Continue = newToken + return statusError +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/event.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/event.go new file mode 100644 index 0000000000..3e5bfb1c63 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/event.go @@ -0,0 +1,71 @@ +/* +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 etcd3 + +import ( + "fmt" + "go.etcd.io/etcd/api/v3/mvccpb" + clientv3 "go.etcd.io/etcd/client/v3" +) + +type event struct { + key string + value []byte + prevValue []byte + rev int64 + isDeleted bool + isCreated bool + isProgressNotify bool +} + +// parseKV converts a KeyValue retrieved from an initial sync() listing to a synthetic isCreated event. +func parseKV(kv *mvccpb.KeyValue) *event { + return &event{ + key: string(kv.Key), + value: kv.Value, + prevValue: nil, + rev: kv.ModRevision, + isDeleted: false, + isCreated: true, + } +} + +func parseEvent(e *clientv3.Event) (*event, error) { + if !e.IsCreate() && e.PrevKv == nil { + // If the previous value is nil, error. One example of how this is possible is if the previous value has been compacted already. + return nil, fmt.Errorf("etcd event received with PrevKv=nil (key=%q, modRevision=%d, type=%s)", string(e.Kv.Key), e.Kv.ModRevision, e.Type.String()) + + } + ret := &event{ + key: string(e.Kv.Key), + value: e.Kv.Value, + rev: e.Kv.ModRevision, + isDeleted: e.Type == clientv3.EventTypeDelete, + isCreated: e.IsCreate(), + } + if e.PrevKv != nil { + ret.prevValue = e.PrevKv.Value + } + return ret, nil +} + +func progressNotifyEvent(rev int64) *event { + return &event{ + rev: rev, + isProgressNotify: true, + } +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/healthcheck.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/healthcheck.go new file mode 100644 index 0000000000..ad051d2d6c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/healthcheck.go @@ -0,0 +1,40 @@ +/* +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 etcd3 + +import ( + "encoding/json" + "fmt" +) + +// etcdHealth encodes data returned from etcd /healthz handler. +type etcdHealth struct { + // Note this has to be public so the json library can modify it. + Health string `json:"health"` +} + +// EtcdHealthCheck decodes data returned from etcd /healthz handler. +func EtcdHealthCheck(data []byte) error { + obj := etcdHealth{} + if err := json.Unmarshal(data, &obj); err != nil { + return err + } + if obj.Health != "true" { + return fmt.Errorf("Unhealthy status: %s", obj.Health) + } + return nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/latency_tracker.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/latency_tracker.go new file mode 100644 index 0000000000..f60210f96c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/latency_tracker.go @@ -0,0 +1,107 @@ +/* +Copyright 2022 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 etcd3 + +import ( + "context" + "time" + + clientv3 "go.etcd.io/etcd/client/v3" + endpointsrequest "k8s.io/apiserver/pkg/endpoints/request" +) + +// NewETCDLatencyTracker returns an implementation of +// clientv3.KV that times the calls from the specified +// 'delegate' KV instance in order to track latency incurred. +func NewETCDLatencyTracker(delegate clientv3.KV) clientv3.KV { + return &clientV3KVLatencyTracker{KV: delegate} +} + +// clientV3KVLatencyTracker decorates a clientv3.KV instance and times +// each call so we can track the latency an API request incurs in etcd +// round trips (the time it takes to send data to etcd and get the +// complete response back) +// +// If an API request involves N (N>=1) round trips to etcd, then we will sum +// up the latenciy incurred in each roundtrip. + +// It uses the context associated with the request in flight, so there +// are no states shared among the requests in flight, and so there is no +// concurrency overhead. +// If the goroutine executing the request handler makes concurrent calls +// to the underlying storage layer, that is protected since the latency +// tracking function TrackStorageLatency is thread safe. +// +// NOTE: Compact is an asynchronous process and is not associated with +// any request, so we will not be tracking its latency. +type clientV3KVLatencyTracker struct { + clientv3.KV +} + +func (c *clientV3KVLatencyTracker) Put(ctx context.Context, key, val string, opts ...clientv3.OpOption) (*clientv3.PutResponse, error) { + startedAt := time.Now() + defer func() { + endpointsrequest.TrackStorageLatency(ctx, time.Since(startedAt)) + }() + + return c.KV.Put(ctx, key, val, opts...) +} + +func (c *clientV3KVLatencyTracker) Get(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.GetResponse, error) { + startedAt := time.Now() + defer func() { + endpointsrequest.TrackStorageLatency(ctx, time.Since(startedAt)) + }() + + return c.KV.Get(ctx, key, opts...) +} + +func (c *clientV3KVLatencyTracker) Delete(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.DeleteResponse, error) { + startedAt := time.Now() + defer func() { + endpointsrequest.TrackStorageLatency(ctx, time.Since(startedAt)) + }() + + return c.KV.Delete(ctx, key, opts...) +} + +func (c *clientV3KVLatencyTracker) Do(ctx context.Context, op clientv3.Op) (clientv3.OpResponse, error) { + startedAt := time.Now() + defer func() { + endpointsrequest.TrackStorageLatency(ctx, time.Since(startedAt)) + }() + + return c.KV.Do(ctx, op) +} + +func (c *clientV3KVLatencyTracker) Txn(ctx context.Context) clientv3.Txn { + return &clientV3TxnTracker{ctx: ctx, Txn: c.KV.Txn(ctx)} +} + +type clientV3TxnTracker struct { + ctx context.Context + clientv3.Txn +} + +func (t *clientV3TxnTracker) Commit() (*clientv3.TxnResponse, error) { + startedAt := time.Now() + defer func() { + endpointsrequest.TrackStorageLatency(t.ctx, time.Since(startedAt)) + }() + + return t.Txn.Commit() +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/lease_manager.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/lease_manager.go new file mode 100644 index 0000000000..12c9d00c76 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/lease_manager.go @@ -0,0 +1,131 @@ +/* +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 etcd3 + +import ( + "context" + "sync" + "time" + + clientv3 "go.etcd.io/etcd/client/v3" + "k8s.io/apiserver/pkg/storage/etcd3/metrics" +) + +const ( + defaultLeaseReuseDurationSeconds = 60 + defaultLeaseMaxObjectCount = 1000 +) + +// LeaseManagerConfig is configuration for creating a lease manager. +type LeaseManagerConfig struct { + // ReuseDurationSeconds specifies time in seconds that each lease is reused + ReuseDurationSeconds int64 + // MaxObjectCount specifies how many objects that a lease can attach + MaxObjectCount int64 +} + +// NewDefaultLeaseManagerConfig creates a LeaseManagerConfig with default values +func NewDefaultLeaseManagerConfig() LeaseManagerConfig { + return LeaseManagerConfig{ + ReuseDurationSeconds: defaultLeaseReuseDurationSeconds, + MaxObjectCount: defaultLeaseMaxObjectCount, + } +} + +// leaseManager is used to manage leases requested from etcd. If a new write +// needs a lease that has similar expiration time to the previous one, the old +// lease will be reused to reduce the overhead of etcd, since lease operations +// are expensive. In the implementation, we only store one previous lease, +// since all the events have the same ttl. +type leaseManager struct { + client *clientv3.Client // etcd client used to grant leases + leaseMu sync.Mutex + prevLeaseID clientv3.LeaseID + prevLeaseExpirationTime time.Time + // The period of time in seconds and percent of TTL that each lease is + // reused. The minimum of them is used to avoid unreasonably large + // numbers. + leaseReuseDurationSeconds int64 + leaseReuseDurationPercent float64 + leaseMaxAttachedObjectCount int64 + leaseAttachedObjectCount int64 +} + +// newDefaultLeaseManager creates a new lease manager using default setting. +func newDefaultLeaseManager(client *clientv3.Client, config LeaseManagerConfig) *leaseManager { + if config.MaxObjectCount <= 0 { + config.MaxObjectCount = defaultLeaseMaxObjectCount + } + return newLeaseManager(client, config.ReuseDurationSeconds, 0.05, config.MaxObjectCount) +} + +// newLeaseManager creates a new lease manager with the number of buffered +// leases, lease reuse duration in seconds and percentage. The percentage +// value x means x*100%. +func newLeaseManager(client *clientv3.Client, leaseReuseDurationSeconds int64, leaseReuseDurationPercent float64, maxObjectCount int64) *leaseManager { + return &leaseManager{ + client: client, + leaseReuseDurationSeconds: leaseReuseDurationSeconds, + leaseReuseDurationPercent: leaseReuseDurationPercent, + leaseMaxAttachedObjectCount: maxObjectCount, + } +} + +// GetLease returns a lease based on requested ttl: if the cached previous +// lease can be reused, reuse it; otherwise request a new one from etcd. +func (l *leaseManager) GetLease(ctx context.Context, ttl int64) (clientv3.LeaseID, error) { + now := time.Now() + l.leaseMu.Lock() + defer l.leaseMu.Unlock() + // check if previous lease can be reused + reuseDurationSeconds := l.getReuseDurationSecondsLocked(ttl) + valid := now.Add(time.Duration(ttl) * time.Second).Before(l.prevLeaseExpirationTime) + sufficient := now.Add(time.Duration(ttl+reuseDurationSeconds) * time.Second).After(l.prevLeaseExpirationTime) + + // We count all operations that happened in the same lease, regardless of success or failure. + // Currently each GetLease call only attach 1 object + l.leaseAttachedObjectCount++ + + if valid && sufficient && l.leaseAttachedObjectCount <= l.leaseMaxAttachedObjectCount { + return l.prevLeaseID, nil + } + + // request a lease with a little extra ttl from etcd + ttl += reuseDurationSeconds + lcr, err := l.client.Lease.Grant(ctx, ttl) + if err != nil { + return clientv3.LeaseID(0), err + } + // cache the new lease id + l.prevLeaseID = lcr.ID + l.prevLeaseExpirationTime = now.Add(time.Duration(ttl) * time.Second) + // refresh count + metrics.UpdateLeaseObjectCount(l.leaseAttachedObjectCount) + l.leaseAttachedObjectCount = 1 + return lcr.ID, nil +} + +// getReuseDurationSecondsLocked returns the reusable duration in seconds +// based on the configuration. Lock has to be acquired before calling this +// function. +func (l *leaseManager) getReuseDurationSecondsLocked(ttl int64) int64 { + reuseDurationSeconds := int64(l.leaseReuseDurationPercent * float64(ttl)) + if reuseDurationSeconds > l.leaseReuseDurationSeconds { + reuseDurationSeconds = l.leaseReuseDurationSeconds + } + return reuseDurationSeconds +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/logger.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/logger.go new file mode 100644 index 0000000000..773d12f6f1 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/logger.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 etcd3 + +import ( + "fmt" + + "google.golang.org/grpc/grpclog" + "k8s.io/klog/v2" +) + +func init() { + grpclog.SetLoggerV2(klogWrapper{}) +} + +type klogWrapper struct{} + +const klogWrapperDepth = 4 + +func (klogWrapper) Info(args ...interface{}) { + if klogV := klog.V(5); klogV.Enabled() { + klogV.InfoSDepth(klogWrapperDepth, fmt.Sprint(args...)) + } +} + +func (klogWrapper) Infoln(args ...interface{}) { + if klogV := klog.V(5); klogV.Enabled() { + klogV.InfoSDepth(klogWrapperDepth, fmt.Sprintln(args...)) + } +} + +func (klogWrapper) Infof(format string, args ...interface{}) { + if klogV := klog.V(5); klogV.Enabled() { + klog.V(5).InfoSDepth(klogWrapperDepth, fmt.Sprintf(format, args...)) + } +} + +func (klogWrapper) Warning(args ...interface{}) { + klog.WarningDepth(klogWrapperDepth, args...) +} + +func (klogWrapper) Warningln(args ...interface{}) { + klog.WarningDepth(klogWrapperDepth, fmt.Sprintln(args...)) +} + +func (klogWrapper) Warningf(format string, args ...interface{}) { + klog.WarningDepth(klogWrapperDepth, fmt.Sprintf(format, args...)) +} + +func (klogWrapper) Error(args ...interface{}) { + klog.ErrorDepth(klogWrapperDepth, args...) +} + +func (klogWrapper) Errorln(args ...interface{}) { + klog.ErrorDepth(klogWrapperDepth, fmt.Sprintln(args...)) +} + +func (klogWrapper) Errorf(format string, args ...interface{}) { + klog.ErrorDepth(klogWrapperDepth, fmt.Sprintf(format, args...)) +} + +func (klogWrapper) Fatal(args ...interface{}) { + klog.FatalDepth(klogWrapperDepth, args...) +} + +func (klogWrapper) Fatalln(args ...interface{}) { + klog.FatalDepth(klogWrapperDepth, fmt.Sprintln(args...)) +} + +func (klogWrapper) Fatalf(format string, args ...interface{}) { + klog.FatalDepth(klogWrapperDepth, fmt.Sprintf(format, args...)) +} + +func (klogWrapper) V(l int) bool { + return bool(klog.V(klog.Level(l)).Enabled()) +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/OWNERS b/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/OWNERS new file mode 100644 index 0000000000..433e84aa3e --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/OWNERS @@ -0,0 +1,4 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - logicalhan diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go new file mode 100644 index 0000000000..6f155c0adb --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go @@ -0,0 +1,208 @@ +/* +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 metrics + +import ( + "sync" + "time" + + compbasemetrics "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +/* + * By default, all the following metrics are defined as falling under + * ALPHA stability level https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/1209-metrics-stability/kubernetes-control-plane-metrics-stability.md#stability-classes) + * + * Promoting the stability level of the metric is a responsibility of the component owner, since it + * involves explicitly acknowledging support for the metric across multiple releases, in accordance with + * the metric stability policy. + */ +var ( + etcdRequestLatency = compbasemetrics.NewHistogramVec( + &compbasemetrics.HistogramOpts{ + Name: "etcd_request_duration_seconds", + Help: "Etcd request latency in seconds for each operation and object type.", + // Etcd request latency in seconds for each operation and object type. + // This metric is used for verifying etcd api call latencies SLO + // keep consistent with apiserver metric 'requestLatencies' in + // staging/src/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go + Buckets: []float64{0.005, 0.025, 0.05, 0.1, 0.2, 0.4, 0.6, 0.8, 1.0, 1.25, 1.5, 2, 3, + 4, 5, 6, 8, 10, 15, 20, 30, 45, 60}, + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"operation", "type"}, + ) + objectCounts = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Name: "apiserver_storage_objects", + Help: "Number of stored objects at the time of last check split by kind.", + StabilityLevel: compbasemetrics.STABLE, + }, + []string{"resource"}, + ) + dbTotalSize = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Subsystem: "apiserver", + Name: "storage_db_total_size_in_bytes", + Help: "Total size of the storage database file physically allocated in bytes.", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"endpoint"}, + ) + etcdEventsReceivedCounts = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Subsystem: "apiserver", + Name: "storage_events_received_total", + Help: "Number of etcd events received split by kind.", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"resource"}, + ) + etcdBookmarkCounts = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Name: "etcd_bookmark_counts", + Help: "Number of etcd bookmarks (progress notify events) split by kind.", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"resource"}, + ) + etcdLeaseObjectCounts = compbasemetrics.NewHistogramVec( + &compbasemetrics.HistogramOpts{ + Name: "etcd_lease_object_counts", + Help: "Number of objects attached to a single etcd lease.", + Buckets: []float64{10, 50, 100, 500, 1000, 2500, 5000}, + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{}, + ) + listStorageCount = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Name: "apiserver_storage_list_total", + Help: "Number of LIST requests served from storage", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"resource"}, + ) + listStorageNumFetched = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Name: "apiserver_storage_list_fetched_objects_total", + Help: "Number of objects read from storage in the course of serving a LIST request", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"resource"}, + ) + listStorageNumSelectorEvals = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Name: "apiserver_storage_list_evaluated_objects_total", + Help: "Number of objects tested in the course of serving a LIST request from storage", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"resource"}, + ) + listStorageNumReturned = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Name: "apiserver_storage_list_returned_objects_total", + Help: "Number of objects returned for a LIST request from storage", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"resource"}, + ) + decodeErrorCounts = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Namespace: "apiserver", + Name: "storage_decode_errors_total", + Help: "Number of stored object decode errors split by object type", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"resource"}, + ) +) + +var registerMetrics sync.Once + +// Register all metrics. +func Register() { + // Register the metrics. + registerMetrics.Do(func() { + legacyregistry.MustRegister(etcdRequestLatency) + legacyregistry.MustRegister(objectCounts) + legacyregistry.MustRegister(dbTotalSize) + legacyregistry.MustRegister(etcdBookmarkCounts) + legacyregistry.MustRegister(etcdLeaseObjectCounts) + legacyregistry.MustRegister(listStorageCount) + legacyregistry.MustRegister(listStorageNumFetched) + legacyregistry.MustRegister(listStorageNumSelectorEvals) + legacyregistry.MustRegister(listStorageNumReturned) + legacyregistry.MustRegister(decodeErrorCounts) + }) +} + +// UpdateObjectCount sets the apiserver_storage_object_counts metric. +func UpdateObjectCount(resourcePrefix string, count int64) { + objectCounts.WithLabelValues(resourcePrefix).Set(float64(count)) +} + +// RecordEtcdRequestLatency sets the etcd_request_duration_seconds metrics. +func RecordEtcdRequestLatency(verb, resource string, startTime time.Time) { + etcdRequestLatency.WithLabelValues(verb, resource).Observe(sinceInSeconds(startTime)) +} + +// RecordEtcdEvent updated the etcd_events_received_total metric. +func RecordEtcdEvent(resource string) { + etcdEventsReceivedCounts.WithLabelValues(resource).Inc() +} + +// RecordEtcdBookmark updates the etcd_bookmark_counts metric. +func RecordEtcdBookmark(resource string) { + etcdBookmarkCounts.WithLabelValues(resource).Inc() +} + +// RecordDecodeError sets the storage_decode_errors metrics. +func RecordDecodeError(resource string) { + decodeErrorCounts.WithLabelValues(resource).Inc() +} + +// Reset resets the etcd_request_duration_seconds metric. +func Reset() { + etcdRequestLatency.Reset() +} + +// sinceInSeconds gets the time since the specified start in seconds. +func sinceInSeconds(start time.Time) float64 { + return time.Since(start).Seconds() +} + +// UpdateEtcdDbSize sets the etcd_db_total_size_in_bytes metric. +func UpdateEtcdDbSize(ep string, size int64) { + dbTotalSize.WithLabelValues(ep).Set(float64(size)) +} + +// UpdateLeaseObjectCount sets the etcd_lease_object_counts metric. +func UpdateLeaseObjectCount(count int64) { + // Currently we only store one previous lease, since all the events have the same ttl. + // See pkg/storage/etcd3/lease_manager.go + etcdLeaseObjectCounts.WithLabelValues().Observe(float64(count)) +} + +// RecordListEtcd3Metrics notes various metrics of the cost to serve a LIST request +func RecordStorageListMetrics(resource string, numFetched, numEvald, numReturned int) { + listStorageCount.WithLabelValues(resource).Inc() + listStorageNumFetched.WithLabelValues(resource).Add(float64(numFetched)) + listStorageNumSelectorEvals.WithLabelValues(resource).Add(float64(numEvald)) + listStorageNumReturned.WithLabelValues(resource).Add(float64(numReturned)) +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go new file mode 100644 index 0000000000..2fc237de33 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go @@ -0,0 +1,1065 @@ +/* +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 etcd3 + +import ( + "bytes" + "context" + "errors" + "fmt" + "path" + "reflect" + "strings" + "time" + + clientv3 "go.etcd.io/etcd/client/v3" + "go.opentelemetry.io/otel/attribute" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/validation/field" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/conversion" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/apiserver/pkg/audit" + "k8s.io/apiserver/pkg/features" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/etcd3/metrics" + "k8s.io/apiserver/pkg/storage/value" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/component-base/tracing" + "k8s.io/klog/v2" +) + +const ( + // maxLimit is a maximum page limit increase used when fetching objects from etcd. + // This limit is used only for increasing page size by kube-apiserver. If request + // specifies larger limit initially, it won't be changed. + maxLimit = 10000 +) + +// authenticatedDataString satisfies the value.Context interface. It uses the key to +// authenticate the stored data. This does not defend against reuse of previously +// encrypted values under the same key, but will prevent an attacker from using an +// encrypted value from a different key. A stronger authenticated data segment would +// include the etcd3 Version field (which is incremented on each write to a key and +// reset when the key is deleted), but an attacker with write access to etcd can +// force deletion and recreation of keys to weaken that angle. +type authenticatedDataString string + +// AuthenticatedData implements the value.Context interface. +func (d authenticatedDataString) AuthenticatedData() []byte { + return []byte(string(d)) +} + +var _ value.Context = authenticatedDataString("") + +type store struct { + client *clientv3.Client + codec runtime.Codec + versioner storage.Versioner + transformer value.Transformer + pathPrefix string + groupResource schema.GroupResource + groupResourceString string + watcher *watcher + pagingEnabled bool + leaseManager *leaseManager +} + +type objState struct { + obj runtime.Object + meta *storage.ResponseMeta + rev int64 + data []byte + stale bool +} + +// New returns an etcd3 implementation of storage.Interface. +func New(c *clientv3.Client, codec runtime.Codec, newFunc func() runtime.Object, prefix string, groupResource schema.GroupResource, transformer value.Transformer, pagingEnabled bool, leaseManagerConfig LeaseManagerConfig) storage.Interface { + return newStore(c, codec, newFunc, prefix, groupResource, transformer, pagingEnabled, leaseManagerConfig) +} + +func newStore(c *clientv3.Client, codec runtime.Codec, newFunc func() runtime.Object, prefix string, groupResource schema.GroupResource, transformer value.Transformer, pagingEnabled bool, leaseManagerConfig LeaseManagerConfig) *store { + versioner := storage.APIObjectVersioner{} + // for compatibility with etcd2 impl. + // no-op for default prefix of '/registry'. + // keeps compatibility with etcd2 impl for custom prefixes that don't start with '/' + pathPrefix := path.Join("/", prefix) + if !strings.HasSuffix(pathPrefix, "/") { + // Ensure the pathPrefix ends in "/" here to simplify key concatenation later. + pathPrefix += "/" + } + result := &store{ + client: c, + codec: codec, + versioner: versioner, + transformer: transformer, + pagingEnabled: pagingEnabled, + pathPrefix: pathPrefix, + groupResource: groupResource, + groupResourceString: groupResource.String(), + watcher: newWatcher(c, codec, groupResource, newFunc, versioner), + leaseManager: newDefaultLeaseManager(c, leaseManagerConfig), + } + return result +} + +// Versioner implements storage.Interface.Versioner. +func (s *store) Versioner() storage.Versioner { + return s.versioner +} + +// Get implements storage.Interface.Get. +func (s *store) Get(ctx context.Context, key string, opts storage.GetOptions, out runtime.Object) error { + preparedKey, err := s.prepareKey(key) + if err != nil { + return err + } + startTime := time.Now() + getResp, err := s.client.KV.Get(ctx, preparedKey) + metrics.RecordEtcdRequestLatency("get", s.groupResourceString, startTime) + if err != nil { + return err + } + if err = s.validateMinimumResourceVersion(opts.ResourceVersion, uint64(getResp.Header.Revision)); err != nil { + return err + } + + if len(getResp.Kvs) == 0 { + if opts.IgnoreNotFound { + return runtime.SetZeroValue(out) + } + return storage.NewKeyNotFoundError(preparedKey, 0) + } + kv := getResp.Kvs[0] + + data, _, err := s.transformer.TransformFromStorage(ctx, kv.Value, authenticatedDataString(preparedKey)) + if err != nil { + return storage.NewInternalError(err.Error()) + } + + err = decode(s.codec, s.versioner, data, out, kv.ModRevision) + if err != nil { + recordDecodeError(s.groupResourceString, preparedKey) + return err + } + return nil +} + +// Create implements storage.Interface.Create. +func (s *store) Create(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error { + preparedKey, err := s.prepareKey(key) + if err != nil { + return err + } + ctx, span := tracing.Start(ctx, "Create etcd3", + attribute.String("audit-id", audit.GetAuditIDTruncated(ctx)), + attribute.String("key", key), + attribute.String("type", getTypeName(obj)), + attribute.String("resource", s.groupResourceString), + ) + defer span.End(500 * time.Millisecond) + if version, err := s.versioner.ObjectResourceVersion(obj); err == nil && version != 0 { + return errors.New("resourceVersion should not be set on objects to be created") + } + if err := s.versioner.PrepareObjectForStorage(obj); err != nil { + return fmt.Errorf("PrepareObjectForStorage failed: %v", err) + } + span.AddEvent("About to Encode") + data, err := runtime.Encode(s.codec, obj) + if err != nil { + span.AddEvent("Encode failed", attribute.Int("len", len(data)), attribute.String("err", err.Error())) + return err + } + span.AddEvent("Encode succeeded", attribute.Int("len", len(data))) + + opts, err := s.ttlOpts(ctx, int64(ttl)) + if err != nil { + return err + } + + newData, err := s.transformer.TransformToStorage(ctx, data, authenticatedDataString(preparedKey)) + if err != nil { + span.AddEvent("TransformToStorage failed", attribute.String("err", err.Error())) + return storage.NewInternalError(err.Error()) + } + span.AddEvent("TransformToStorage succeeded") + + startTime := time.Now() + txnResp, err := s.client.KV.Txn(ctx).If( + notFound(preparedKey), + ).Then( + clientv3.OpPut(preparedKey, string(newData), opts...), + ).Commit() + metrics.RecordEtcdRequestLatency("create", s.groupResourceString, startTime) + if err != nil { + span.AddEvent("Txn call failed", attribute.String("err", err.Error())) + return err + } + span.AddEvent("Txn call succeeded") + + if !txnResp.Succeeded { + return storage.NewKeyExistsError(preparedKey, 0) + } + + if out != nil { + putResp := txnResp.Responses[0].GetResponsePut() + err = decode(s.codec, s.versioner, data, out, putResp.Header.Revision) + if err != nil { + span.AddEvent("decode failed", attribute.Int("len", len(data)), attribute.String("err", err.Error())) + recordDecodeError(s.groupResourceString, preparedKey) + return err + } + span.AddEvent("decode succeeded", attribute.Int("len", len(data))) + } + return nil +} + +// Delete implements storage.Interface.Delete. +func (s *store) Delete( + ctx context.Context, key string, out runtime.Object, preconditions *storage.Preconditions, + validateDeletion storage.ValidateObjectFunc, cachedExistingObject runtime.Object) error { + preparedKey, err := s.prepareKey(key) + if err != nil { + return err + } + v, err := conversion.EnforcePtr(out) + if err != nil { + return fmt.Errorf("unable to convert output object to pointer: %v", err) + } + return s.conditionalDelete(ctx, preparedKey, out, v, preconditions, validateDeletion, cachedExistingObject) +} + +func (s *store) conditionalDelete( + ctx context.Context, key string, out runtime.Object, v reflect.Value, preconditions *storage.Preconditions, + validateDeletion storage.ValidateObjectFunc, cachedExistingObject runtime.Object) error { + getCurrentState := func() (*objState, error) { + startTime := time.Now() + getResp, err := s.client.KV.Get(ctx, key) + metrics.RecordEtcdRequestLatency("get", s.groupResourceString, startTime) + if err != nil { + return nil, err + } + return s.getState(ctx, getResp, key, v, false) + } + + var origState *objState + var err error + var origStateIsCurrent bool + if cachedExistingObject != nil { + origState, err = s.getStateFromObject(cachedExistingObject) + } else { + origState, err = getCurrentState() + origStateIsCurrent = true + } + if err != nil { + return err + } + + for { + if preconditions != nil { + if err := preconditions.Check(key, origState.obj); err != nil { + if origStateIsCurrent { + return err + } + + // It's possible we're working with stale data. + // Remember the revision of the potentially stale data and the resulting update error + cachedRev := origState.rev + cachedUpdateErr := err + + // Actually fetch + origState, err = getCurrentState() + if err != nil { + return err + } + origStateIsCurrent = true + + // it turns out our cached data was not stale, return the error + if cachedRev == origState.rev { + return cachedUpdateErr + } + + // Retry + continue + } + } + if err := validateDeletion(ctx, origState.obj); err != nil { + if origStateIsCurrent { + return err + } + + // It's possible we're working with stale data. + // Remember the revision of the potentially stale data and the resulting update error + cachedRev := origState.rev + cachedUpdateErr := err + + // Actually fetch + origState, err = getCurrentState() + if err != nil { + return err + } + origStateIsCurrent = true + + // it turns out our cached data was not stale, return the error + if cachedRev == origState.rev { + return cachedUpdateErr + } + + // Retry + continue + } + + startTime := time.Now() + txnResp, err := s.client.KV.Txn(ctx).If( + clientv3.Compare(clientv3.ModRevision(key), "=", origState.rev), + ).Then( + clientv3.OpDelete(key), + ).Else( + clientv3.OpGet(key), + ).Commit() + metrics.RecordEtcdRequestLatency("delete", s.groupResourceString, startTime) + if err != nil { + return err + } + if !txnResp.Succeeded { + getResp := (*clientv3.GetResponse)(txnResp.Responses[0].GetResponseRange()) + klog.V(4).Infof("deletion of %s failed because of a conflict, going to retry", key) + origState, err = s.getState(ctx, getResp, key, v, false) + if err != nil { + return err + } + origStateIsCurrent = true + continue + } + + if len(txnResp.Responses) == 0 || txnResp.Responses[0].GetResponseDeleteRange() == nil { + return errors.New(fmt.Sprintf("invalid DeleteRange response: %v", txnResp.Responses)) + } + deleteResp := txnResp.Responses[0].GetResponseDeleteRange() + if deleteResp.Header == nil { + return errors.New("invalid DeleteRange response - nil header") + } + err = decode(s.codec, s.versioner, origState.data, out, deleteResp.Header.Revision) + if err != nil { + recordDecodeError(s.groupResourceString, key) + return err + } + return nil + } +} + +// GuaranteedUpdate implements storage.Interface.GuaranteedUpdate. +func (s *store) GuaranteedUpdate( + ctx context.Context, key string, destination runtime.Object, ignoreNotFound bool, + preconditions *storage.Preconditions, tryUpdate storage.UpdateFunc, cachedExistingObject runtime.Object) error { + preparedKey, err := s.prepareKey(key) + if err != nil { + return err + } + ctx, span := tracing.Start(ctx, "GuaranteedUpdate etcd3", + attribute.String("audit-id", audit.GetAuditIDTruncated(ctx)), + attribute.String("key", key), + attribute.String("type", getTypeName(destination)), + attribute.String("resource", s.groupResourceString)) + defer span.End(500 * time.Millisecond) + + v, err := conversion.EnforcePtr(destination) + if err != nil { + return fmt.Errorf("unable to convert output object to pointer: %v", err) + } + + getCurrentState := func() (*objState, error) { + startTime := time.Now() + getResp, err := s.client.KV.Get(ctx, preparedKey) + metrics.RecordEtcdRequestLatency("get", s.groupResourceString, startTime) + if err != nil { + return nil, err + } + return s.getState(ctx, getResp, preparedKey, v, ignoreNotFound) + } + + var origState *objState + var origStateIsCurrent bool + if cachedExistingObject != nil { + origState, err = s.getStateFromObject(cachedExistingObject) + } else { + origState, err = getCurrentState() + origStateIsCurrent = true + } + if err != nil { + return err + } + span.AddEvent("initial value restored") + + transformContext := authenticatedDataString(preparedKey) + for { + if err := preconditions.Check(preparedKey, origState.obj); err != nil { + // If our data is already up to date, return the error + if origStateIsCurrent { + return err + } + + // It's possible we were working with stale data + // Actually fetch + origState, err = getCurrentState() + if err != nil { + return err + } + origStateIsCurrent = true + // Retry + continue + } + + ret, ttl, err := s.updateState(origState, tryUpdate) + if err != nil { + // If our data is already up to date, return the error + if origStateIsCurrent { + return err + } + + // It's possible we were working with stale data + // Remember the revision of the potentially stale data and the resulting update error + cachedRev := origState.rev + cachedUpdateErr := err + + // Actually fetch + origState, err = getCurrentState() + if err != nil { + return err + } + origStateIsCurrent = true + + // it turns out our cached data was not stale, return the error + if cachedRev == origState.rev { + return cachedUpdateErr + } + + // Retry + continue + } + + span.AddEvent("About to Encode") + data, err := runtime.Encode(s.codec, ret) + if err != nil { + span.AddEvent("Encode failed", attribute.Int("len", len(data)), attribute.String("err", err.Error())) + return err + } + span.AddEvent("Encode succeeded", attribute.Int("len", len(data))) + if !origState.stale && bytes.Equal(data, origState.data) { + // if we skipped the original Get in this loop, we must refresh from + // etcd in order to be sure the data in the store is equivalent to + // our desired serialization + if !origStateIsCurrent { + origState, err = getCurrentState() + if err != nil { + return err + } + origStateIsCurrent = true + if !bytes.Equal(data, origState.data) { + // original data changed, restart loop + continue + } + } + // recheck that the data from etcd is not stale before short-circuiting a write + if !origState.stale { + err = decode(s.codec, s.versioner, origState.data, destination, origState.rev) + if err != nil { + recordDecodeError(s.groupResourceString, preparedKey) + return err + } + return nil + } + } + + newData, err := s.transformer.TransformToStorage(ctx, data, transformContext) + if err != nil { + span.AddEvent("TransformToStorage failed", attribute.String("err", err.Error())) + return storage.NewInternalError(err.Error()) + } + span.AddEvent("TransformToStorage succeeded") + + opts, err := s.ttlOpts(ctx, int64(ttl)) + if err != nil { + return err + } + span.AddEvent("Transaction prepared") + + startTime := time.Now() + txnResp, err := s.client.KV.Txn(ctx).If( + clientv3.Compare(clientv3.ModRevision(preparedKey), "=", origState.rev), + ).Then( + clientv3.OpPut(preparedKey, string(newData), opts...), + ).Else( + clientv3.OpGet(preparedKey), + ).Commit() + metrics.RecordEtcdRequestLatency("update", s.groupResourceString, startTime) + if err != nil { + span.AddEvent("Txn call failed", attribute.String("err", err.Error())) + return err + } + span.AddEvent("Txn call completed") + span.AddEvent("Transaction committed") + if !txnResp.Succeeded { + getResp := (*clientv3.GetResponse)(txnResp.Responses[0].GetResponseRange()) + klog.V(4).Infof("GuaranteedUpdate of %s failed because of a conflict, going to retry", preparedKey) + origState, err = s.getState(ctx, getResp, preparedKey, v, ignoreNotFound) + if err != nil { + return err + } + span.AddEvent("Retry value restored") + origStateIsCurrent = true + continue + } + putResp := txnResp.Responses[0].GetResponsePut() + + err = decode(s.codec, s.versioner, data, destination, putResp.Header.Revision) + if err != nil { + span.AddEvent("decode failed", attribute.Int("len", len(data)), attribute.String("err", err.Error())) + recordDecodeError(s.groupResourceString, preparedKey) + return err + } + span.AddEvent("decode succeeded", attribute.Int("len", len(data))) + return nil + } +} + +func getNewItemFunc(listObj runtime.Object, v reflect.Value) func() runtime.Object { + // For unstructured lists with a target group/version, preserve the group/version in the instantiated list items + if unstructuredList, isUnstructured := listObj.(*unstructured.UnstructuredList); isUnstructured { + if apiVersion := unstructuredList.GetAPIVersion(); len(apiVersion) > 0 { + return func() runtime.Object { + return &unstructured.Unstructured{Object: map[string]interface{}{"apiVersion": apiVersion}} + } + } + } + + // Otherwise just instantiate an empty item + elem := v.Type().Elem() + return func() runtime.Object { + return reflect.New(elem).Interface().(runtime.Object) + } +} + +func (s *store) Count(key string) (int64, error) { + preparedKey, err := s.prepareKey(key) + if err != nil { + return 0, err + } + + // We need to make sure the key ended with "/" so that we only get children "directories". + // e.g. if we have key "/a", "/a/b", "/ab", getting keys with prefix "/a" will return all three, + // while with prefix "/a/" will return only "/a/b" which is the correct answer. + if !strings.HasSuffix(preparedKey, "/") { + preparedKey += "/" + } + + startTime := time.Now() + getResp, err := s.client.KV.Get(context.Background(), preparedKey, clientv3.WithRange(clientv3.GetPrefixRangeEnd(preparedKey)), clientv3.WithCountOnly()) + metrics.RecordEtcdRequestLatency("listWithCount", preparedKey, startTime) + if err != nil { + return 0, err + } + return getResp.Count, nil +} + +// GetList implements storage.Interface. +func (s *store) GetList(ctx context.Context, key string, opts storage.ListOptions, listObj runtime.Object) error { + preparedKey, err := s.prepareKey(key) + if err != nil { + return err + } + recursive := opts.Recursive + resourceVersion := opts.ResourceVersion + match := opts.ResourceVersionMatch + pred := opts.Predicate + ctx, span := tracing.Start(ctx, fmt.Sprintf("List(recursive=%v) etcd3", recursive), + attribute.String("audit-id", audit.GetAuditIDTruncated(ctx)), + attribute.String("key", key), + attribute.String("resourceVersion", resourceVersion), + attribute.String("resourceVersionMatch", string(match)), + attribute.Int("limit", int(pred.Limit)), + attribute.String("continue", pred.Continue)) + defer span.End(500 * time.Millisecond) + listPtr, err := meta.GetItemsPtr(listObj) + if err != nil { + return err + } + v, err := conversion.EnforcePtr(listPtr) + if err != nil || v.Kind() != reflect.Slice { + return fmt.Errorf("need ptr to slice: %v", err) + } + + // For recursive lists, we need to make sure the key ended with "/" so that we only + // get children "directories". e.g. if we have key "/a", "/a/b", "/ab", getting keys + // with prefix "/a" will return all three, while with prefix "/a/" will return only + // "/a/b" which is the correct answer. + if recursive && !strings.HasSuffix(preparedKey, "/") { + preparedKey += "/" + } + keyPrefix := preparedKey + + // set the appropriate clientv3 options to filter the returned data set + var limitOption *clientv3.OpOption + limit := pred.Limit + var paging bool + options := make([]clientv3.OpOption, 0, 4) + if s.pagingEnabled && pred.Limit > 0 { + paging = true + options = append(options, clientv3.WithLimit(limit)) + limitOption = &options[len(options)-1] + } + + newItemFunc := getNewItemFunc(listObj, v) + + var fromRV *uint64 + if len(resourceVersion) > 0 { + parsedRV, err := s.versioner.ParseResourceVersion(resourceVersion) + if err != nil { + return apierrors.NewBadRequest(fmt.Sprintf("invalid resource version: %v", err)) + } + fromRV = &parsedRV + } + + var returnedRV, continueRV, withRev int64 + var continueKey string + switch { + case recursive && s.pagingEnabled && len(pred.Continue) > 0: + continueKey, continueRV, err = storage.DecodeContinue(pred.Continue, keyPrefix) + if err != nil { + return apierrors.NewBadRequest(fmt.Sprintf("invalid continue token: %v", err)) + } + + if len(resourceVersion) > 0 && resourceVersion != "0" { + return apierrors.NewBadRequest("specifying resource version is not allowed when using continue") + } + + rangeEnd := clientv3.GetPrefixRangeEnd(keyPrefix) + options = append(options, clientv3.WithRange(rangeEnd)) + preparedKey = continueKey + + // If continueRV > 0, the LIST request needs a specific resource version. + // continueRV==0 is invalid. + // If continueRV < 0, the request is for the latest resource version. + if continueRV > 0 { + withRev = continueRV + returnedRV = continueRV + } + case recursive && s.pagingEnabled && pred.Limit > 0: + if fromRV != nil { + switch match { + case metav1.ResourceVersionMatchNotOlderThan: + // The not older than constraint is checked after we get a response from etcd, + // and returnedRV is then set to the revision we get from the etcd response. + case metav1.ResourceVersionMatchExact: + returnedRV = int64(*fromRV) + withRev = returnedRV + case "": // legacy case + if *fromRV > 0 { + returnedRV = int64(*fromRV) + withRev = returnedRV + } + default: + return fmt.Errorf("unknown ResourceVersionMatch value: %v", match) + } + } + + rangeEnd := clientv3.GetPrefixRangeEnd(keyPrefix) + options = append(options, clientv3.WithRange(rangeEnd)) + default: + if fromRV != nil { + switch match { + case metav1.ResourceVersionMatchNotOlderThan: + // The not older than constraint is checked after we get a response from etcd, + // and returnedRV is then set to the revision we get from the etcd response. + case metav1.ResourceVersionMatchExact: + returnedRV = int64(*fromRV) + withRev = returnedRV + case "": // legacy case + default: + return fmt.Errorf("unknown ResourceVersionMatch value: %v", match) + } + } + + if recursive { + options = append(options, clientv3.WithPrefix()) + } + } + if withRev != 0 { + options = append(options, clientv3.WithRev(withRev)) + } + + // loop until we have filled the requested limit from etcd or there are no more results + var lastKey []byte + var hasMore bool + var getResp *clientv3.GetResponse + var numFetched int + var numEvald int + // Because these metrics are for understanding the costs of handling LIST requests, + // get them recorded even in error cases. + defer func() { + numReturn := v.Len() + metrics.RecordStorageListMetrics(s.groupResourceString, numFetched, numEvald, numReturn) + }() + for { + startTime := time.Now() + getResp, err = s.client.KV.Get(ctx, preparedKey, options...) + if recursive { + metrics.RecordEtcdRequestLatency("list", s.groupResourceString, startTime) + } else { + metrics.RecordEtcdRequestLatency("get", s.groupResourceString, startTime) + } + if err != nil { + return interpretListError(err, len(pred.Continue) > 0, continueKey, keyPrefix) + } + numFetched += len(getResp.Kvs) + if err = s.validateMinimumResourceVersion(resourceVersion, uint64(getResp.Header.Revision)); err != nil { + return err + } + hasMore = getResp.More + + if len(getResp.Kvs) == 0 && getResp.More { + return fmt.Errorf("no results were found, but etcd indicated there were more values remaining") + } + + // avoid small allocations for the result slice, since this can be called in many + // different contexts and we don't know how significantly the result will be filtered + if pred.Empty() { + growSlice(v, len(getResp.Kvs)) + } else { + growSlice(v, 2048, len(getResp.Kvs)) + } + + // take items from the response until the bucket is full, filtering as we go + for i, kv := range getResp.Kvs { + if paging && int64(v.Len()) >= pred.Limit { + hasMore = true + break + } + lastKey = kv.Key + + data, _, err := s.transformer.TransformFromStorage(ctx, kv.Value, authenticatedDataString(kv.Key)) + if err != nil { + return storage.NewInternalErrorf("unable to transform key %q: %v", kv.Key, err) + } + + if err := appendListItem(v, data, uint64(kv.ModRevision), pred, s.codec, s.versioner, newItemFunc); err != nil { + recordDecodeError(s.groupResourceString, string(kv.Key)) + return err + } + numEvald++ + + // free kv early. Long lists can take O(seconds) to decode. + getResp.Kvs[i] = nil + } + + // indicate to the client which resource version was returned + if returnedRV == 0 { + returnedRV = getResp.Header.Revision + } + + // no more results remain or we didn't request paging + if !hasMore || !paging { + break + } + // we're paging but we have filled our bucket + if int64(v.Len()) >= pred.Limit { + break + } + + if limit < maxLimit { + // We got incomplete result due to field/label selector dropping the object. + // Double page size to reduce total number of calls to etcd. + limit *= 2 + if limit > maxLimit { + limit = maxLimit + } + *limitOption = clientv3.WithLimit(limit) + } + preparedKey = string(lastKey) + "\x00" + if withRev == 0 { + withRev = returnedRV + options = append(options, clientv3.WithRev(withRev)) + } + } + if v.IsNil() { + // Ensure that we never return a nil Items pointer in the result for consistency. + v.Set(reflect.MakeSlice(v.Type(), 0, 0)) + } + + // instruct the client to begin querying from immediately after the last key we returned + // we never return a key that the client wouldn't be allowed to see + if hasMore { + // we want to start immediately after the last key + next, err := storage.EncodeContinue(string(lastKey)+"\x00", keyPrefix, returnedRV) + if err != nil { + return err + } + var remainingItemCount *int64 + // getResp.Count counts in objects that do not match the pred. + // Instead of returning inaccurate count for non-empty selectors, we return nil. + // Only set remainingItemCount if the predicate is empty. + if utilfeature.DefaultFeatureGate.Enabled(features.RemainingItemCount) { + if pred.Empty() { + c := int64(getResp.Count - pred.Limit) + remainingItemCount = &c + } + } + return s.versioner.UpdateList(listObj, uint64(returnedRV), next, remainingItemCount) + } + + // no continuation + return s.versioner.UpdateList(listObj, uint64(returnedRV), "", nil) +} + +// growSlice takes a slice value and grows its capacity up +// to the maximum of the passed sizes or maxCapacity, whichever +// is smaller. Above maxCapacity decisions about allocation are left +// to the Go runtime on append. This allows a caller to make an +// educated guess about the potential size of the total list while +// still avoiding overly aggressive initial allocation. If sizes +// is empty maxCapacity will be used as the size to grow. +func growSlice(v reflect.Value, maxCapacity int, sizes ...int) { + cap := v.Cap() + max := cap + for _, size := range sizes { + if size > max { + max = size + } + } + if len(sizes) == 0 || max > maxCapacity { + max = maxCapacity + } + if max <= cap { + return + } + if v.Len() > 0 { + extra := reflect.MakeSlice(v.Type(), v.Len(), max) + reflect.Copy(extra, v) + v.Set(extra) + } else { + extra := reflect.MakeSlice(v.Type(), 0, max) + v.Set(extra) + } +} + +// Watch implements storage.Interface.Watch. +func (s *store) Watch(ctx context.Context, key string, opts storage.ListOptions) (watch.Interface, error) { + if opts.SendInitialEvents != nil { + return nil, apierrors.NewInvalid( + schema.GroupKind{Group: s.groupResource.Group, Kind: s.groupResource.Resource}, + "", + field.ErrorList{field.Forbidden(field.NewPath("sendInitialEvents"), "for watch is unsupported by an etcd cluster")}, + ) + } + preparedKey, err := s.prepareKey(key) + if err != nil { + return nil, err + } + rev, err := s.versioner.ParseResourceVersion(opts.ResourceVersion) + if err != nil { + return nil, err + } + return s.watcher.Watch(ctx, preparedKey, int64(rev), opts.Recursive, opts.ProgressNotify, s.transformer, opts.Predicate) +} + +func (s *store) getState(ctx context.Context, getResp *clientv3.GetResponse, key string, v reflect.Value, ignoreNotFound bool) (*objState, error) { + state := &objState{ + meta: &storage.ResponseMeta{}, + } + + if u, ok := v.Addr().Interface().(runtime.Unstructured); ok { + state.obj = u.NewEmptyInstance() + } else { + state.obj = reflect.New(v.Type()).Interface().(runtime.Object) + } + + if len(getResp.Kvs) == 0 { + if !ignoreNotFound { + return nil, storage.NewKeyNotFoundError(key, 0) + } + if err := runtime.SetZeroValue(state.obj); err != nil { + return nil, err + } + } else { + data, stale, err := s.transformer.TransformFromStorage(ctx, getResp.Kvs[0].Value, authenticatedDataString(key)) + if err != nil { + return nil, storage.NewInternalError(err.Error()) + } + state.rev = getResp.Kvs[0].ModRevision + state.meta.ResourceVersion = uint64(state.rev) + state.data = data + state.stale = stale + if err := decode(s.codec, s.versioner, state.data, state.obj, state.rev); err != nil { + recordDecodeError(s.groupResourceString, key) + return nil, err + } + } + return state, nil +} + +func (s *store) getStateFromObject(obj runtime.Object) (*objState, error) { + state := &objState{ + obj: obj, + meta: &storage.ResponseMeta{}, + } + + rv, err := s.versioner.ObjectResourceVersion(obj) + if err != nil { + return nil, fmt.Errorf("couldn't get resource version: %v", err) + } + state.rev = int64(rv) + state.meta.ResourceVersion = uint64(state.rev) + + // Compute the serialized form - for that we need to temporarily clean + // its resource version field (those are not stored in etcd). + if err := s.versioner.PrepareObjectForStorage(obj); err != nil { + return nil, fmt.Errorf("PrepareObjectForStorage failed: %v", err) + } + state.data, err = runtime.Encode(s.codec, obj) + if err != nil { + return nil, err + } + if err := s.versioner.UpdateObject(state.obj, uint64(rv)); err != nil { + klog.Errorf("failed to update object version: %v", err) + } + return state, nil +} + +func (s *store) updateState(st *objState, userUpdate storage.UpdateFunc) (runtime.Object, uint64, error) { + ret, ttlPtr, err := userUpdate(st.obj, *st.meta) + if err != nil { + return nil, 0, err + } + + if err := s.versioner.PrepareObjectForStorage(ret); err != nil { + return nil, 0, fmt.Errorf("PrepareObjectForStorage failed: %v", err) + } + var ttl uint64 + if ttlPtr != nil { + ttl = *ttlPtr + } + return ret, ttl, nil +} + +// ttlOpts returns client options based on given ttl. +// ttl: if ttl is non-zero, it will attach the key to a lease with ttl of roughly the same length +func (s *store) ttlOpts(ctx context.Context, ttl int64) ([]clientv3.OpOption, error) { + if ttl == 0 { + return nil, nil + } + id, err := s.leaseManager.GetLease(ctx, ttl) + if err != nil { + return nil, err + } + return []clientv3.OpOption{clientv3.WithLease(id)}, nil +} + +// validateMinimumResourceVersion returns a 'too large resource' version error when the provided minimumResourceVersion is +// greater than the most recent actualRevision available from storage. +func (s *store) validateMinimumResourceVersion(minimumResourceVersion string, actualRevision uint64) error { + if minimumResourceVersion == "" { + return nil + } + minimumRV, err := s.versioner.ParseResourceVersion(minimumResourceVersion) + if err != nil { + return apierrors.NewBadRequest(fmt.Sprintf("invalid resource version: %v", err)) + } + // Enforce the storage.Interface guarantee that the resource version of the returned data + // "will be at least 'resourceVersion'". + if minimumRV > actualRevision { + return storage.NewTooLargeResourceVersionError(minimumRV, actualRevision, 0) + } + return nil +} + +func (s *store) prepareKey(key string) (string, error) { + if key == ".." || + strings.HasPrefix(key, "../") || + strings.HasSuffix(key, "/..") || + strings.Contains(key, "/../") { + return "", fmt.Errorf("invalid key: %q", key) + } + if key == "." || + strings.HasPrefix(key, "./") || + strings.HasSuffix(key, "/.") || + strings.Contains(key, "/./") { + return "", fmt.Errorf("invalid key: %q", key) + } + if key == "" || key == "/" { + return "", fmt.Errorf("empty key: %q", key) + } + // We ensured that pathPrefix ends in '/' in construction, so skip any leading '/' in the key now. + startIndex := 0 + if key[0] == '/' { + startIndex = 1 + } + return s.pathPrefix + key[startIndex:], nil +} + +// decode decodes value of bytes into object. It will also set the object resource version to rev. +// On success, objPtr would be set to the object. +func decode(codec runtime.Codec, versioner storage.Versioner, value []byte, objPtr runtime.Object, rev int64) error { + if _, err := conversion.EnforcePtr(objPtr); err != nil { + return fmt.Errorf("unable to convert output object to pointer: %v", err) + } + _, _, err := codec.Decode(value, nil, objPtr) + if err != nil { + return err + } + // being unable to set the version does not prevent the object from being extracted + if err := versioner.UpdateObject(objPtr, uint64(rev)); err != nil { + klog.Errorf("failed to update object version: %v", err) + } + return nil +} + +// appendListItem decodes and appends the object (if it passes filter) to v, which must be a slice. +func appendListItem(v reflect.Value, data []byte, rev uint64, pred storage.SelectionPredicate, codec runtime.Codec, versioner storage.Versioner, newItemFunc func() runtime.Object) error { + obj, _, err := codec.Decode(data, nil, newItemFunc()) + if err != nil { + return err + } + // being unable to set the version does not prevent the object from being extracted + if err := versioner.UpdateObject(obj, rev); err != nil { + klog.Errorf("failed to update object version: %v", err) + } + if matched, err := pred.Matches(obj); err == nil && matched { + v.Set(reflect.Append(v, reflect.ValueOf(obj).Elem())) + } + return nil +} + +// recordDecodeError record decode error split by object type. +func recordDecodeError(resource string, key string) { + metrics.RecordDecodeError(resource) + klog.V(4).Infof("Decoding %s \"%s\" failed", resource, key) +} + +func notFound(key string) clientv3.Cmp { + return clientv3.Compare(clientv3.ModRevision(key), "=", 0) +} + +// getTypeName returns type name of an object for reporting purposes. +func getTypeName(obj interface{}) string { + return reflect.TypeOf(obj).String() +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go new file mode 100644 index 0000000000..49d9005fc6 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go @@ -0,0 +1,499 @@ +/* +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 etcd3 + +import ( + "context" + "fmt" + "os" + "reflect" + "strconv" + "strings" + "sync" + + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/etcd3/metrics" + "k8s.io/apiserver/pkg/storage/value" + utilflowcontrol "k8s.io/apiserver/pkg/util/flowcontrol" + + clientv3 "go.etcd.io/etcd/client/v3" + + "k8s.io/klog/v2" +) + +const ( + // We have set a buffer in order to reduce times of context switches. + incomingBufSize = 100 + outgoingBufSize = 100 +) + +// fatalOnDecodeError is used during testing to panic the server if watcher encounters a decoding error +var fatalOnDecodeError = false + +func init() { + // check to see if we are running in a test environment + TestOnlySetFatalOnDecodeError(true) + fatalOnDecodeError, _ = strconv.ParseBool(os.Getenv("KUBE_PANIC_WATCH_DECODE_ERROR")) +} + +// TestOnlySetFatalOnDecodeError should only be used for cases where decode errors are expected and need to be tested. e.g. conversion webhooks. +func TestOnlySetFatalOnDecodeError(b bool) { + fatalOnDecodeError = b +} + +type watcher struct { + client *clientv3.Client + codec runtime.Codec + newFunc func() runtime.Object + objectType string + groupResource schema.GroupResource + versioner storage.Versioner +} + +// watchChan implements watch.Interface. +type watchChan struct { + watcher *watcher + transformer value.Transformer + key string + initialRev int64 + recursive bool + progressNotify bool + internalPred storage.SelectionPredicate + ctx context.Context + cancel context.CancelFunc + incomingEventChan chan *event + resultChan chan watch.Event + errChan chan error +} + +func newWatcher(client *clientv3.Client, codec runtime.Codec, groupResource schema.GroupResource, newFunc func() runtime.Object, versioner storage.Versioner) *watcher { + res := &watcher{ + client: client, + codec: codec, + groupResource: groupResource, + newFunc: newFunc, + versioner: versioner, + } + if newFunc == nil { + res.objectType = "" + } else { + res.objectType = reflect.TypeOf(newFunc()).String() + } + return res +} + +// Watch watches on a key and returns a watch.Interface that transfers relevant notifications. +// If rev is zero, it will return the existing object(s) and then start watching from +// the maximum revision+1 from returned objects. +// If rev is non-zero, it will watch events happened after given revision. +// If recursive is false, it watches on given key. +// If recursive is true, it watches any children and directories under the key, excluding the root key itself. +// pred must be non-nil. Only if pred matches the change, it will be returned. +func (w *watcher) Watch(ctx context.Context, key string, rev int64, recursive, progressNotify bool, transformer value.Transformer, pred storage.SelectionPredicate) (watch.Interface, error) { + if recursive && !strings.HasSuffix(key, "/") { + key += "/" + } + wc := w.createWatchChan(ctx, key, rev, recursive, progressNotify, transformer, pred) + go wc.run() + + // For etcd watch we don't have an easy way to answer whether the watch + // has already caught up. So in the initial version (given that watchcache + // is by default enabled for all resources but Events), we just deliver + // the initialization signal immediately. Improving this will be explored + // in the future. + utilflowcontrol.WatchInitialized(ctx) + + return wc, nil +} + +func (w *watcher) createWatchChan(ctx context.Context, key string, rev int64, recursive, progressNotify bool, transformer value.Transformer, pred storage.SelectionPredicate) *watchChan { + wc := &watchChan{ + watcher: w, + transformer: transformer, + key: key, + initialRev: rev, + recursive: recursive, + progressNotify: progressNotify, + internalPred: pred, + incomingEventChan: make(chan *event, incomingBufSize), + resultChan: make(chan watch.Event, outgoingBufSize), + errChan: make(chan error, 1), + } + if pred.Empty() { + // The filter doesn't filter out any object. + wc.internalPred = storage.Everything + } + + // The etcd server waits until it cannot find a leader for 3 election + // timeouts to cancel existing streams. 3 is currently a hard coded + // constant. The election timeout defaults to 1000ms. If the cluster is + // healthy, when the leader is stopped, the leadership transfer should be + // smooth. (leader transfers its leadership before stopping). If leader is + // hard killed, other servers will take an election timeout to realize + // leader lost and start campaign. + wc.ctx, wc.cancel = context.WithCancel(clientv3.WithRequireLeader(ctx)) + return wc +} + +type etcdError interface { + Code() grpccodes.Code + Error() string +} + +type grpcError interface { + GRPCStatus() *grpcstatus.Status +} + +func isCancelError(err error) bool { + if err == nil { + return false + } + if err == context.Canceled { + return true + } + if etcdErr, ok := err.(etcdError); ok && etcdErr.Code() == grpccodes.Canceled { + return true + } + if grpcErr, ok := err.(grpcError); ok && grpcErr.GRPCStatus().Code() == grpccodes.Canceled { + return true + } + return false +} + +func (wc *watchChan) run() { + watchClosedCh := make(chan struct{}) + go wc.startWatching(watchClosedCh) + + var resultChanWG sync.WaitGroup + resultChanWG.Add(1) + go wc.processEvent(&resultChanWG) + + select { + case err := <-wc.errChan: + if isCancelError(err) { + break + } + errResult := transformErrorToEvent(err) + if errResult != nil { + // error result is guaranteed to be received by user before closing ResultChan. + select { + case wc.resultChan <- *errResult: + case <-wc.ctx.Done(): // user has given up all results + } + } + case <-watchClosedCh: + case <-wc.ctx.Done(): // user cancel + } + + // We use wc.ctx to reap all goroutines. Under whatever condition, we should stop them all. + // It's fine to double cancel. + wc.cancel() + + // we need to wait until resultChan wouldn't be used anymore + resultChanWG.Wait() + close(wc.resultChan) +} + +func (wc *watchChan) Stop() { + wc.cancel() +} + +func (wc *watchChan) ResultChan() <-chan watch.Event { + return wc.resultChan +} + +// sync tries to retrieve existing data and send them to process. +// The revision to watch will be set to the revision in response. +// All events sent will have isCreated=true +func (wc *watchChan) sync() error { + opts := []clientv3.OpOption{} + if wc.recursive { + opts = append(opts, clientv3.WithPrefix()) + } + getResp, err := wc.watcher.client.Get(wc.ctx, wc.key, opts...) + if err != nil { + return err + } + wc.initialRev = getResp.Header.Revision + for _, kv := range getResp.Kvs { + wc.sendEvent(parseKV(kv)) + } + return nil +} + +func logWatchChannelErr(err error) { + switch { + case strings.Contains(err.Error(), "mvcc: required revision has been compacted"): + // mvcc revision compaction which is regarded as warning, not error + klog.Warningf("watch chan error: %v", err) + case isCancelError(err): + // expected when watches close, no need to log + default: + klog.Errorf("watch chan error: %v", err) + } +} + +// startWatching does: +// - get current objects if initialRev=0; set initialRev to current rev +// - watch on given key and send events to process. +func (wc *watchChan) startWatching(watchClosedCh chan struct{}) { + if wc.initialRev == 0 { + if err := wc.sync(); err != nil { + klog.Errorf("failed to sync with latest state: %v", err) + wc.sendError(err) + return + } + } + opts := []clientv3.OpOption{clientv3.WithRev(wc.initialRev + 1), clientv3.WithPrevKV()} + if wc.recursive { + opts = append(opts, clientv3.WithPrefix()) + } + if wc.progressNotify { + opts = append(opts, clientv3.WithProgressNotify()) + } + wch := wc.watcher.client.Watch(wc.ctx, wc.key, opts...) + for wres := range wch { + if wres.Err() != nil { + err := wres.Err() + // If there is an error on server (e.g. compaction), the channel will return it before closed. + logWatchChannelErr(err) + wc.sendError(err) + return + } + if wres.IsProgressNotify() { + wc.sendEvent(progressNotifyEvent(wres.Header.GetRevision())) + metrics.RecordEtcdBookmark(wc.watcher.groupResource.String()) + continue + } + + for _, e := range wres.Events { + metrics.RecordEtcdEvent(wc.watcher.groupResource.String()) + parsedEvent, err := parseEvent(e) + if err != nil { + logWatchChannelErr(err) + wc.sendError(err) + return + } + wc.sendEvent(parsedEvent) + } + } + // When we come to this point, it's only possible that client side ends the watch. + // e.g. cancel the context, close the client. + // If this watch chan is broken and context isn't cancelled, other goroutines will still hang. + // We should notify the main thread that this goroutine has exited. + close(watchClosedCh) +} + +// processEvent processes events from etcd watcher and sends results to resultChan. +func (wc *watchChan) processEvent(wg *sync.WaitGroup) { + defer wg.Done() + + for { + select { + case e := <-wc.incomingEventChan: + res := wc.transform(e) + if res == nil { + continue + } + if len(wc.resultChan) == outgoingBufSize { + klog.V(3).InfoS("Fast watcher, slow processing. Probably caused by slow dispatching events to watchers", "outgoingEvents", outgoingBufSize, "objectType", wc.watcher.objectType, "groupResource", wc.watcher.groupResource) + } + // If user couldn't receive results fast enough, we also block incoming events from watcher. + // Because storing events in local will cause more memory usage. + // The worst case would be closing the fast watcher. + select { + case wc.resultChan <- *res: + case <-wc.ctx.Done(): + return + } + case <-wc.ctx.Done(): + return + } + } +} + +func (wc *watchChan) filter(obj runtime.Object) bool { + if wc.internalPred.Empty() { + return true + } + matched, err := wc.internalPred.Matches(obj) + return err == nil && matched +} + +func (wc *watchChan) acceptAll() bool { + return wc.internalPred.Empty() +} + +// transform transforms an event into a result for user if not filtered. +func (wc *watchChan) transform(e *event) (res *watch.Event) { + curObj, oldObj, err := wc.prepareObjs(e) + if err != nil { + klog.Errorf("failed to prepare current and previous objects: %v", err) + wc.sendError(err) + return nil + } + + switch { + case e.isProgressNotify: + if wc.watcher.newFunc == nil { + return nil + } + object := wc.watcher.newFunc() + if err := wc.watcher.versioner.UpdateObject(object, uint64(e.rev)); err != nil { + klog.Errorf("failed to propagate object version: %v", err) + return nil + } + res = &watch.Event{ + Type: watch.Bookmark, + Object: object, + } + case e.isDeleted: + if !wc.filter(oldObj) { + return nil + } + res = &watch.Event{ + Type: watch.Deleted, + Object: oldObj, + } + case e.isCreated: + if !wc.filter(curObj) { + return nil + } + res = &watch.Event{ + Type: watch.Added, + Object: curObj, + } + default: + if wc.acceptAll() { + res = &watch.Event{ + Type: watch.Modified, + Object: curObj, + } + return res + } + curObjPasses := wc.filter(curObj) + oldObjPasses := wc.filter(oldObj) + switch { + case curObjPasses && oldObjPasses: + res = &watch.Event{ + Type: watch.Modified, + Object: curObj, + } + case curObjPasses && !oldObjPasses: + res = &watch.Event{ + Type: watch.Added, + Object: curObj, + } + case !curObjPasses && oldObjPasses: + res = &watch.Event{ + Type: watch.Deleted, + Object: oldObj, + } + } + } + return res +} + +func transformErrorToEvent(err error) *watch.Event { + err = interpretWatchError(err) + if _, ok := err.(apierrors.APIStatus); !ok { + err = apierrors.NewInternalError(err) + } + status := err.(apierrors.APIStatus).Status() + return &watch.Event{ + Type: watch.Error, + Object: &status, + } +} + +func (wc *watchChan) sendError(err error) { + select { + case wc.errChan <- err: + case <-wc.ctx.Done(): + } +} + +func (wc *watchChan) sendEvent(e *event) { + if len(wc.incomingEventChan) == incomingBufSize { + klog.V(3).InfoS("Fast watcher, slow processing. Probably caused by slow decoding, user not receiving fast, or other processing logic", "incomingEvents", incomingBufSize, "objectType", wc.watcher.objectType, "groupResource", wc.watcher.groupResource) + } + select { + case wc.incomingEventChan <- e: + case <-wc.ctx.Done(): + } +} + +func (wc *watchChan) prepareObjs(e *event) (curObj runtime.Object, oldObj runtime.Object, err error) { + if e.isProgressNotify { + // progressNotify events doesn't contain neither current nor previous object version, + return nil, nil, nil + } + + if !e.isDeleted { + data, _, err := wc.transformer.TransformFromStorage(wc.ctx, e.value, authenticatedDataString(e.key)) + if err != nil { + return nil, nil, err + } + curObj, err = decodeObj(wc.watcher.codec, wc.watcher.versioner, data, e.rev) + if err != nil { + return nil, nil, err + } + } + // We need to decode prevValue, only if this is deletion event or + // the underlying filter doesn't accept all objects (otherwise we + // know that the filter for previous object will return true and + // we need the object only to compute whether it was filtered out + // before). + if len(e.prevValue) > 0 && (e.isDeleted || !wc.acceptAll()) { + data, _, err := wc.transformer.TransformFromStorage(wc.ctx, e.prevValue, authenticatedDataString(e.key)) + if err != nil { + return nil, nil, err + } + // Note that this sends the *old* object with the etcd revision for the time at + // which it gets deleted. + oldObj, err = decodeObj(wc.watcher.codec, wc.watcher.versioner, data, e.rev) + if err != nil { + return nil, nil, err + } + } + return curObj, oldObj, nil +} + +func decodeObj(codec runtime.Codec, versioner storage.Versioner, data []byte, rev int64) (_ runtime.Object, err error) { + obj, err := runtime.Decode(codec, []byte(data)) + if err != nil { + if fatalOnDecodeError { + // we are running in a test environment and thus an + // error here is due to a coder mistake if the defer + // does not catch it + panic(err) + } + return nil, err + } + // ensure resource version is set on the object we load from etcd + if err := versioner.UpdateObject(obj, uint64(rev)); err != nil { + return nil, fmt.Errorf("failure to version api object (%d) %#v: %v", rev, obj, err) + } + return obj, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/interfaces.go b/vendor/k8s.io/apiserver/pkg/storage/interfaces.go new file mode 100644 index 0000000000..daf30a242f --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/interfaces.go @@ -0,0 +1,277 @@ +/* +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 storage + +import ( + "context" + "fmt" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" +) + +// Versioner abstracts setting and retrieving metadata fields from database response +// onto the object ot list. It is required to maintain storage invariants - updating an +// object twice with the same data except for the ResourceVersion and SelfLink must be +// a no-op. A resourceVersion of type uint64 is a 'raw' resourceVersion, +// intended to be sent directly to or from the backend. A resourceVersion of +// type string is a 'safe' resourceVersion, intended for consumption by users. +type Versioner interface { + // UpdateObject sets storage metadata into an API object. Returns an error if the object + // cannot be updated correctly. May return nil if the requested object does not need metadata + // from database. + UpdateObject(obj runtime.Object, resourceVersion uint64) error + // UpdateList sets the resource version into an API list object. Returns an error if the object + // cannot be updated correctly. May return nil if the requested object does not need metadata from + // database. continueValue is optional and indicates that more results are available if the client + // passes that value to the server in a subsequent call. remainingItemCount indicates the number + // of remaining objects if the list is partial. The remainingItemCount field is omitted during + // serialization if it is set to nil. + UpdateList(obj runtime.Object, resourceVersion uint64, continueValue string, remainingItemCount *int64) error + // PrepareObjectForStorage should set SelfLink and ResourceVersion to the empty value. Should + // return an error if the specified object cannot be updated. + PrepareObjectForStorage(obj runtime.Object) error + // ObjectResourceVersion returns the resource version (for persistence) of the specified object. + // Should return an error if the specified object does not have a persistable version. + ObjectResourceVersion(obj runtime.Object) (uint64, error) + + // ParseResourceVersion takes a resource version argument and + // converts it to the storage backend. For watch we should pass to helper.Watch(). + // Because resourceVersion is an opaque value, the default watch + // behavior for non-zero watch is to watch the next value (if you pass + // "1", you will see updates from "2" onwards). + ParseResourceVersion(resourceVersion string) (uint64, error) +} + +// ResponseMeta contains information about the database metadata that is associated with +// an object. It abstracts the actual underlying objects to prevent coupling with concrete +// database and to improve testability. +type ResponseMeta struct { + // TTL is the time to live of the node that contained the returned object. It may be + // zero or negative in some cases (objects may be expired after the requested + // expiration time due to server lag). + TTL int64 + // The resource version of the node that contained the returned object. + ResourceVersion uint64 +} + +// IndexerFunc is a function that for a given object computes +// `` for a particular ``. +type IndexerFunc func(obj runtime.Object) string + +// IndexerFuncs is a mapping from `` to function that +// for a given object computes ``. +type IndexerFuncs map[string]IndexerFunc + +// Everything accepts all objects. +var Everything = SelectionPredicate{ + Label: labels.Everything(), + Field: fields.Everything(), +} + +// MatchValue defines a pair (``, ``). +type MatchValue struct { + IndexName string + Value string +} + +// Pass an UpdateFunc to Interface.GuaranteedUpdate to make an update +// that is guaranteed to succeed. +// See the comment for GuaranteedUpdate for more details. +type UpdateFunc func(input runtime.Object, res ResponseMeta) (output runtime.Object, ttl *uint64, err error) + +// ValidateObjectFunc is a function to act on a given object. An error may be returned +// if the hook cannot be completed. The function may NOT transform the provided +// object. +type ValidateObjectFunc func(ctx context.Context, obj runtime.Object) error + +// ValidateAllObjectFunc is a "admit everything" instance of ValidateObjectFunc. +func ValidateAllObjectFunc(ctx context.Context, obj runtime.Object) error { + return nil +} + +// Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out. +type Preconditions struct { + // Specifies the target UID. + // +optional + UID *types.UID `json:"uid,omitempty"` + // Specifies the target ResourceVersion + // +optional + ResourceVersion *string `json:"resourceVersion,omitempty"` +} + +// NewUIDPreconditions returns a Preconditions with UID set. +func NewUIDPreconditions(uid string) *Preconditions { + u := types.UID(uid) + return &Preconditions{UID: &u} +} + +func (p *Preconditions) Check(key string, obj runtime.Object) error { + if p == nil { + return nil + } + objMeta, err := meta.Accessor(obj) + if err != nil { + return NewInternalErrorf( + "can't enforce preconditions %v on un-introspectable object %v, got error: %v", + *p, + obj, + err) + } + if p.UID != nil && *p.UID != objMeta.GetUID() { + err := fmt.Sprintf( + "Precondition failed: UID in precondition: %v, UID in object meta: %v", + *p.UID, + objMeta.GetUID()) + return NewInvalidObjError(key, err) + } + if p.ResourceVersion != nil && *p.ResourceVersion != objMeta.GetResourceVersion() { + err := fmt.Sprintf( + "Precondition failed: ResourceVersion in precondition: %v, ResourceVersion in object meta: %v", + *p.ResourceVersion, + objMeta.GetResourceVersion()) + return NewInvalidObjError(key, err) + } + return nil +} + +// Interface offers a common interface for object marshaling/unmarshaling operations and +// hides all the storage-related operations behind it. +type Interface interface { + // Returns Versioner associated with this interface. + Versioner() Versioner + + // Create adds a new object at a key unless it already exists. 'ttl' is time-to-live + // in seconds (0 means forever). If no error is returned and out is not nil, out will be + // set to the read value from database. + Create(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error + + // Delete removes the specified key and returns the value that existed at that spot. + // If key didn't exist, it will return NotFound storage error. + // If 'cachedExistingObject' is non-nil, it can be used as a suggestion about the + // current version of the object to avoid read operation from storage to get it. + // However, the implementations have to retry in case suggestion is stale. + Delete( + ctx context.Context, key string, out runtime.Object, preconditions *Preconditions, + validateDeletion ValidateObjectFunc, cachedExistingObject runtime.Object) error + + // Watch begins watching the specified key. Events are decoded into API objects, + // and any items selected by 'p' are sent down to returned watch.Interface. + // resourceVersion may be used to specify what version to begin watching, + // which should be the current resourceVersion, and no longer rv+1 + // (e.g. reconnecting without missing any updates). + // If resource version is "0", this interface will get current object at given key + // and send it in an "ADDED" event, before watch starts. + Watch(ctx context.Context, key string, opts ListOptions) (watch.Interface, error) + + // Get unmarshals object found at key into objPtr. On a not found error, will either + // return a zero object of the requested type, or an error, depending on 'opts.ignoreNotFound'. + // Treats empty responses and nil response nodes exactly like a not found error. + // The returned contents may be delayed, but it is guaranteed that they will + // match 'opts.ResourceVersion' according 'opts.ResourceVersionMatch'. + Get(ctx context.Context, key string, opts GetOptions, objPtr runtime.Object) error + + // GetList unmarshalls objects found at key into a *List api object (an object + // that satisfies runtime.IsList definition). + // If 'opts.Recursive' is false, 'key' is used as an exact match. If `opts.Recursive' + // is true, 'key' is used as a prefix. + // The returned contents may be delayed, but it is guaranteed that they will + // match 'opts.ResourceVersion' according 'opts.ResourceVersionMatch'. + GetList(ctx context.Context, key string, opts ListOptions, listObj runtime.Object) error + + // GuaranteedUpdate keeps calling 'tryUpdate()' to update key 'key' (of type 'destination') + // retrying the update until success if there is index conflict. + // Note that object passed to tryUpdate may change across invocations of tryUpdate() if + // other writers are simultaneously updating it, so tryUpdate() needs to take into account + // the current contents of the object when deciding how the update object should look. + // If the key doesn't exist, it will return NotFound storage error if ignoreNotFound=false + // else `destination` will be set to the zero value of it's type. + // If the eventual successful invocation of `tryUpdate` returns an output with the same serialized + // contents as the input, it won't perform any update, but instead set `destination` to an object with those + // contents. + // If 'cachedExistingObject' is non-nil, it can be used as a suggestion about the + // current version of the object to avoid read operation from storage to get it. + // However, the implementations have to retry in case suggestion is stale. + // + // Example: + // + // s := /* implementation of Interface */ + // err := s.GuaranteedUpdate( + // "myKey", &MyType{}, true, preconditions, + // func(input runtime.Object, res ResponseMeta) (runtime.Object, *uint64, error) { + // // Before each invocation of the user defined function, "input" is reset to + // // current contents for "myKey" in database. + // curr := input.(*MyType) // Guaranteed to succeed. + // + // // Make the modification + // curr.Counter++ + // + // // Return the modified object - return an error to stop iterating. Return + // // a uint64 to alter the TTL on the object, or nil to keep it the same value. + // return cur, nil, nil + // }, cachedExistingObject + // ) + GuaranteedUpdate( + ctx context.Context, key string, destination runtime.Object, ignoreNotFound bool, + preconditions *Preconditions, tryUpdate UpdateFunc, cachedExistingObject runtime.Object) error + + // Count returns number of different entries under the key (generally being path prefix). + Count(key string) (int64, error) +} + +// GetOptions provides the options that may be provided for storage get operations. +type GetOptions struct { + // IgnoreNotFound determines what is returned if the requested object is not found. If + // true, a zero object is returned. If false, an error is returned. + IgnoreNotFound bool + // ResourceVersion provides a resource version constraint to apply to the get operation + // as a "not older than" constraint: the result contains data at least as new as the provided + // ResourceVersion. The newest available data is preferred, but any data not older than this + // ResourceVersion may be served. + ResourceVersion string +} + +// ListOptions provides the options that may be provided for storage list operations. +type ListOptions struct { + // ResourceVersion provides a resource version constraint to apply to the list operation + // as a "not older than" constraint: the result contains data at least as new as the provided + // ResourceVersion. The newest available data is preferred, but any data not older than this + // ResourceVersion may be served. + ResourceVersion string + // ResourceVersionMatch provides the rule for how the resource version constraint applies. If set + // to the default value "" the legacy resource version semantic apply. + ResourceVersionMatch metav1.ResourceVersionMatch + // Predicate provides the selection rules for the list operation. + Predicate SelectionPredicate + // Recursive determines whether the list or watch is defined for a single object located at the + // given key, or for the whole set of objects with the given key as a prefix. + Recursive bool + // ProgressNotify determines whether storage-originated bookmark (progress notify) events should + // be delivered to the users. The option is ignored for non-watch requests. + ProgressNotify bool + // SendInitialEvents, when set together with Watch option, + // begin the watch stream with synthetic init events to build the + // whole state of all resources followed by a synthetic "Bookmark" + // event containing a ResourceVersion after which the server + // continues streaming events. + SendInitialEvents *bool +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/selection_predicate.go b/vendor/k8s.io/apiserver/pkg/storage/selection_predicate.go new file mode 100644 index 0000000000..a0a14366f2 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/selection_predicate.go @@ -0,0 +1,171 @@ +/* +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 storage + +import ( + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +// AttrFunc returns label and field sets and the uninitialized flag for List or Watch to match. +// In any failure to parse given object, it returns error. +type AttrFunc func(obj runtime.Object) (labels.Set, fields.Set, error) + +// FieldMutationFunc allows the mutation of the field selection fields. It is mutating to +// avoid the extra allocation on this common path +type FieldMutationFunc func(obj runtime.Object, fieldSet fields.Set) error + +func DefaultClusterScopedAttr(obj runtime.Object) (labels.Set, fields.Set, error) { + metadata, err := meta.Accessor(obj) + if err != nil { + return nil, nil, err + } + fieldSet := fields.Set{ + "metadata.name": metadata.GetName(), + } + + return labels.Set(metadata.GetLabels()), fieldSet, nil +} + +func DefaultNamespaceScopedAttr(obj runtime.Object) (labels.Set, fields.Set, error) { + metadata, err := meta.Accessor(obj) + if err != nil { + return nil, nil, err + } + fieldSet := fields.Set{ + "metadata.name": metadata.GetName(), + "metadata.namespace": metadata.GetNamespace(), + } + + return labels.Set(metadata.GetLabels()), fieldSet, nil +} + +func (f AttrFunc) WithFieldMutation(fieldMutator FieldMutationFunc) AttrFunc { + return func(obj runtime.Object) (labels.Set, fields.Set, error) { + labelSet, fieldSet, err := f(obj) + if err != nil { + return nil, nil, err + } + if err := fieldMutator(obj, fieldSet); err != nil { + return nil, nil, err + } + return labelSet, fieldSet, nil + } +} + +// SelectionPredicate is used to represent the way to select objects from api storage. +type SelectionPredicate struct { + Label labels.Selector + Field fields.Selector + GetAttrs AttrFunc + IndexLabels []string + IndexFields []string + Limit int64 + Continue string + AllowWatchBookmarks bool +} + +// Matches returns true if the given object's labels and fields (as +// returned by s.GetAttrs) match s.Label and s.Field. An error is +// returned if s.GetAttrs fails. +func (s *SelectionPredicate) Matches(obj runtime.Object) (bool, error) { + if s.Empty() { + return true, nil + } + labels, fields, err := s.GetAttrs(obj) + if err != nil { + return false, err + } + matched := s.Label.Matches(labels) + if matched && s.Field != nil { + matched = matched && s.Field.Matches(fields) + } + return matched, nil +} + +// MatchesObjectAttributes returns true if the given labels and fields +// match s.Label and s.Field. +func (s *SelectionPredicate) MatchesObjectAttributes(l labels.Set, f fields.Set) bool { + if s.Label.Empty() && s.Field.Empty() { + return true + } + matched := s.Label.Matches(l) + if matched && s.Field != nil { + matched = (matched && s.Field.Matches(f)) + } + return matched +} + +// MatchesSingleNamespace will return (namespace, true) if and only if s.Field matches on the object's +// namespace. +func (s *SelectionPredicate) MatchesSingleNamespace() (string, bool) { + if len(s.Continue) > 0 { + return "", false + } + if namespace, ok := s.Field.RequiresExactMatch("metadata.namespace"); ok { + return namespace, true + } + return "", false +} + +// MatchesSingle will return (name, true) if and only if s.Field matches on the object's +// name. +func (s *SelectionPredicate) MatchesSingle() (string, bool) { + if len(s.Continue) > 0 { + return "", false + } + // TODO: should be namespace.name + if name, ok := s.Field.RequiresExactMatch("metadata.name"); ok { + return name, true + } + return "", false +} + +// Empty returns true if the predicate performs no filtering. +func (s *SelectionPredicate) Empty() bool { + return s.Label.Empty() && s.Field.Empty() +} + +// For any index defined by IndexFields, if a matcher can match only (a subset) +// of objects that return for a given index, a pair (, ) +// wil be returned. +func (s *SelectionPredicate) MatcherIndex() []MatchValue { + var result []MatchValue + for _, field := range s.IndexFields { + if value, ok := s.Field.RequiresExactMatch(field); ok { + result = append(result, MatchValue{IndexName: FieldIndex(field), Value: value}) + } + } + for _, label := range s.IndexLabels { + if value, ok := s.Label.RequiresExactMatch(label); ok { + result = append(result, MatchValue{IndexName: LabelIndex(label), Value: value}) + } + } + return result +} + +// LabelIndex add prefix for label index. +func LabelIndex(label string) string { + return "l:" + label +} + +// FiledIndex add prefix for field index. +func FieldIndex(field string) string { + return "f:" + field +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/storagebackend/OWNERS b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/OWNERS new file mode 100644 index 0000000000..c29de755d0 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/OWNERS @@ -0,0 +1,6 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +reviewers: + - lavalamp + - smarterclayton + - wojtek-t diff --git a/vendor/k8s.io/apiserver/pkg/storage/storagebackend/config.go b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/config.go new file mode 100644 index 0000000000..47534c9781 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/config.go @@ -0,0 +1,128 @@ +/* +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 storagebackend + +import ( + "time" + + oteltrace "go.opentelemetry.io/otel/trace" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/server/egressselector" + "k8s.io/apiserver/pkg/storage/etcd3" + "k8s.io/apiserver/pkg/storage/value" + flowcontrolrequest "k8s.io/apiserver/pkg/util/flowcontrol/request" +) + +const ( + StorageTypeUnset = "" + StorageTypeETCD2 = "etcd2" + StorageTypeETCD3 = "etcd3" + + DefaultCompactInterval = 5 * time.Minute + DefaultDBMetricPollInterval = 30 * time.Second + DefaultHealthcheckTimeout = 2 * time.Second + DefaultReadinessTimeout = 2 * time.Second +) + +// TransportConfig holds all connection related info, i.e. equal TransportConfig means equal servers we talk to. +type TransportConfig struct { + // ServerList is the list of storage servers to connect with. + ServerList []string + // TLS credentials + KeyFile string + CertFile string + TrustedCAFile string + // function to determine the egress dialer. (i.e. konnectivity server dialer) + EgressLookup egressselector.Lookup + // The TracerProvider can add tracing the connection + TracerProvider oteltrace.TracerProvider +} + +// Config is configuration for creating a storage backend. +type Config struct { + // Type defines the type of storage backend. Default ("") is "etcd3". + Type string + // Prefix is the prefix to all keys passed to storage.Interface methods. + Prefix string + // Transport holds all connection related info, i.e. equal TransportConfig means equal servers we talk to. + Transport TransportConfig + // Paging indicates whether the server implementation should allow paging (if it is + // supported). This is generally configured by feature gating, or by a specific + // resource type not wishing to allow paging, and is not intended for end users to + // set. + Paging bool + + Codec runtime.Codec + // EncodeVersioner is the same groupVersioner used to build the + // storage encoder. Given a list of kinds the input object might belong + // to, the EncodeVersioner outputs the gvk the object will be + // converted to before persisted in etcd. + EncodeVersioner runtime.GroupVersioner + // Transformer allows the value to be transformed prior to persisting into etcd. + Transformer value.Transformer + + // CompactionInterval is an interval of requesting compaction from apiserver. + // If the value is 0, no compaction will be issued. + CompactionInterval time.Duration + // CountMetricPollPeriod specifies how often should count metric be updated + CountMetricPollPeriod time.Duration + // DBMetricPollInterval specifies how often should storage backend metric be updated. + DBMetricPollInterval time.Duration + // HealthcheckTimeout specifies the timeout used when checking health + HealthcheckTimeout time.Duration + // ReadycheckTimeout specifies the timeout used when checking readiness + ReadycheckTimeout time.Duration + + LeaseManagerConfig etcd3.LeaseManagerConfig + + // StorageObjectCountTracker is used to keep track of the total + // number of objects in the storage per resource. + StorageObjectCountTracker flowcontrolrequest.StorageObjectCountTracker +} + +// ConfigForResource is a Config specialized to a particular `schema.GroupResource` +type ConfigForResource struct { + // Config is the resource-independent configuration + Config + + // GroupResource is the relevant one + GroupResource schema.GroupResource +} + +// ForResource specializes to the given resource +func (config *Config) ForResource(resource schema.GroupResource) *ConfigForResource { + return &ConfigForResource{ + Config: *config, + GroupResource: resource, + } +} + +func NewDefaultConfig(prefix string, codec runtime.Codec) *Config { + return &Config{ + Paging: true, + Prefix: prefix, + Codec: codec, + CompactionInterval: DefaultCompactInterval, + DBMetricPollInterval: DefaultDBMetricPollInterval, + HealthcheckTimeout: DefaultHealthcheckTimeout, + ReadycheckTimeout: DefaultReadinessTimeout, + LeaseManagerConfig: etcd3.NewDefaultLeaseManagerConfig(), + Transport: TransportConfig{TracerProvider: oteltrace.NewNoopTracerProvider()}, + } +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go new file mode 100644 index 0000000000..c178596495 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go @@ -0,0 +1,434 @@ +/* +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 factory + +import ( + "context" + "fmt" + "log" + "net" + "net/url" + "os" + "path" + "strings" + "sync" + "time" + + grpcprom "github.com/grpc-ecosystem/go-grpc-prometheus" + "go.etcd.io/etcd/client/pkg/v3/logutil" + "go.etcd.io/etcd/client/pkg/v3/transport" + clientv3 "go.etcd.io/etcd/client/v3" + "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "golang.org/x/time/rate" + "google.golang.org/grpc" + + "k8s.io/apimachinery/pkg/runtime" + utilnet "k8s.io/apimachinery/pkg/util/net" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/wait" + genericfeatures "k8s.io/apiserver/pkg/features" + "k8s.io/apiserver/pkg/server/egressselector" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/etcd3" + "k8s.io/apiserver/pkg/storage/etcd3/metrics" + "k8s.io/apiserver/pkg/storage/storagebackend" + "k8s.io/apiserver/pkg/storage/value/encrypt/identity" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/component-base/metrics/legacyregistry" + tracing "k8s.io/component-base/tracing" + "k8s.io/klog/v2" +) + +const ( + // The short keepalive timeout and interval have been chosen to aggressively + // detect a failed etcd server without introducing much overhead. + keepaliveTime = 30 * time.Second + keepaliveTimeout = 10 * time.Second + + // dialTimeout is the timeout for failing to establish a connection. + // It is set to 20 seconds as times shorter than that will cause TLS connections to fail + // on heavily loaded arm64 CPUs (issue #64649) + dialTimeout = 20 * time.Second + + dbMetricsMonitorJitter = 0.5 +) + +// TODO(negz): Stop using a package scoped logger. At the time of writing we're +// creating an etcd client for each CRD. We need to pass each etcd client a +// logger or each client will create its own, which comes with a significant +// memory cost (around 20% of the API server's memory when hundreds of CRDs are +// present). The correct fix here is to not create a client per CRD. See +// https://github.com/kubernetes/kubernetes/issues/111476 for more. +var etcd3ClientLogger *zap.Logger + +func init() { + // grpcprom auto-registers (via an init function) their client metrics, since we are opting out of + // using the global prometheus registry and using our own wrapped global registry, + // we need to explicitly register these metrics to our global registry here. + // For reference: https://github.com/kubernetes/kubernetes/pull/81387 + legacyregistry.RawMustRegister(grpcprom.DefaultClientMetrics) + dbMetricsMonitors = make(map[string]struct{}) + + l, err := logutil.CreateDefaultZapLogger(etcdClientDebugLevel()) + if err != nil { + l = zap.NewNop() + } + etcd3ClientLogger = l.Named("etcd-client") +} + +// etcdClientDebugLevel translates ETCD_CLIENT_DEBUG into zap log level. +// NOTE(negz): This is a copy of a private etcd client function: +// https://github.com/etcd-io/etcd/blob/v3.5.4/client/v3/logger.go#L47 +func etcdClientDebugLevel() zapcore.Level { + envLevel := os.Getenv("ETCD_CLIENT_DEBUG") + if envLevel == "" || envLevel == "true" { + return zapcore.InfoLevel + } + var l zapcore.Level + if err := l.Set(envLevel); err == nil { + log.Printf("Deprecated env ETCD_CLIENT_DEBUG value. Using default level: 'info'") + return zapcore.InfoLevel + } + return l +} + +func newETCD3HealthCheck(c storagebackend.Config, stopCh <-chan struct{}) (func() error, error) { + timeout := storagebackend.DefaultHealthcheckTimeout + if c.HealthcheckTimeout != time.Duration(0) { + timeout = c.HealthcheckTimeout + } + return newETCD3Check(c, timeout, stopCh) +} + +func newETCD3ReadyCheck(c storagebackend.Config, stopCh <-chan struct{}) (func() error, error) { + timeout := storagebackend.DefaultReadinessTimeout + if c.ReadycheckTimeout != time.Duration(0) { + timeout = c.ReadycheckTimeout + } + return newETCD3Check(c, timeout, stopCh) +} + +// atomic error acts as a cache for atomically store an error +// the error is only updated if the timestamp is more recent than +// current stored error. +type atomicLastError struct { + mu sync.RWMutex + err error + timestamp time.Time +} + +func (a *atomicLastError) Store(err error, t time.Time) { + a.mu.Lock() + defer a.mu.Unlock() + if a.timestamp.IsZero() || a.timestamp.Before(t) { + a.err = err + a.timestamp = t + } +} + +func (a *atomicLastError) Load() error { + a.mu.RLock() + defer a.mu.RUnlock() + return a.err +} + +func newETCD3Check(c storagebackend.Config, timeout time.Duration, stopCh <-chan struct{}) (func() error, error) { + // constructing the etcd v3 client blocks and times out if etcd is not available. + // retry in a loop in the background until we successfully create the client, storing the client or error encountered + + lock := sync.RWMutex{} + var client *clientv3.Client + clientErr := fmt.Errorf("etcd client connection not yet established") + + go wait.PollUntil(time.Second, func() (bool, error) { + newClient, err := newETCD3Client(c.Transport) + lock.Lock() + defer lock.Unlock() + // Ensure that server is already not shutting down. + select { + case <-stopCh: + if err == nil { + newClient.Close() + } + return true, nil + default: + } + if err != nil { + clientErr = err + return false, nil + } + client = newClient + clientErr = nil + return true, nil + }, stopCh) + + // Close the client on shutdown. + go func() { + defer utilruntime.HandleCrash() + <-stopCh + + lock.Lock() + defer lock.Unlock() + if client != nil { + client.Close() + clientErr = fmt.Errorf("server is shutting down") + } + }() + + // limit to a request every half of the configured timeout with a maximum burst of one + // rate limited requests will receive the last request sent error (note: not the last received response) + limiter := rate.NewLimiter(rate.Every(timeout/2), 1) + // initial state is the clientErr + lastError := &atomicLastError{err: fmt.Errorf("etcd client connection not yet established")} + + return func() error { + // Given that client is closed on shutdown we hold the lock for + // the entire period of healthcheck call to ensure that client will + // not be closed during healthcheck. + // Given that healthchecks has a 2s timeout, worst case of blocking + // shutdown for additional 2s seems acceptable. + lock.RLock() + defer lock.RUnlock() + + if clientErr != nil { + return clientErr + } + if limiter.Allow() == false { + return lastError.Load() + } + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + // See https://github.com/etcd-io/etcd/blob/c57f8b3af865d1b531b979889c602ba14377420e/etcdctl/ctlv3/command/ep_command.go#L118 + now := time.Now() + _, err := client.Get(ctx, path.Join("/", c.Prefix, "health")) + if err != nil { + err = fmt.Errorf("error getting data from etcd: %w", err) + } + lastError.Store(err, now) + return err + }, nil +} + +var newETCD3Client = func(c storagebackend.TransportConfig) (*clientv3.Client, error) { + tlsInfo := transport.TLSInfo{ + CertFile: c.CertFile, + KeyFile: c.KeyFile, + TrustedCAFile: c.TrustedCAFile, + } + tlsConfig, err := tlsInfo.ClientConfig() + if err != nil { + return nil, err + } + // NOTE: Client relies on nil tlsConfig + // for non-secure connections, update the implicit variable + if len(c.CertFile) == 0 && len(c.KeyFile) == 0 && len(c.TrustedCAFile) == 0 { + tlsConfig = nil + } + networkContext := egressselector.Etcd.AsNetworkContext() + var egressDialer utilnet.DialFunc + if c.EgressLookup != nil { + egressDialer, err = c.EgressLookup(networkContext) + if err != nil { + return nil, err + } + } + dialOptions := []grpc.DialOption{ + grpc.WithBlock(), // block until the underlying connection is up + // use chained interceptors so that the default (retry and backoff) interceptors are added. + // otherwise they will be overwritten by the metric interceptor. + // + // these optional interceptors will be placed after the default ones. + // which seems to be what we want as the metrics will be collected on each attempt (retry) + grpc.WithChainUnaryInterceptor(grpcprom.UnaryClientInterceptor), + grpc.WithChainStreamInterceptor(grpcprom.StreamClientInterceptor), + } + if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.APIServerTracing) { + tracingOpts := []otelgrpc.Option{ + otelgrpc.WithPropagators(tracing.Propagators()), + otelgrpc.WithTracerProvider(c.TracerProvider), + } + // Even with Noop TracerProvider, the otelgrpc still handles context propagation. + // See https://github.com/open-telemetry/opentelemetry-go/tree/main/example/passthrough + dialOptions = append(dialOptions, + grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor(tracingOpts...)), + grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor(tracingOpts...))) + } + if egressDialer != nil { + dialer := func(ctx context.Context, addr string) (net.Conn, error) { + if strings.Contains(addr, "//") { + // etcd client prior to 3.5 passed URLs to dialer, normalize to address + u, err := url.Parse(addr) + if err != nil { + return nil, err + } + addr = u.Host + } + return egressDialer(ctx, "tcp", addr) + } + dialOptions = append(dialOptions, grpc.WithContextDialer(dialer)) + } + + cfg := clientv3.Config{ + DialTimeout: dialTimeout, + DialKeepAliveTime: keepaliveTime, + DialKeepAliveTimeout: keepaliveTimeout, + DialOptions: dialOptions, + Endpoints: c.ServerList, + TLS: tlsConfig, + Logger: etcd3ClientLogger, + } + + return clientv3.New(cfg) +} + +type runningCompactor struct { + interval time.Duration + cancel context.CancelFunc + client *clientv3.Client + refs int +} + +var ( + // compactorsMu guards access to compactors map + compactorsMu sync.Mutex + compactors = map[string]*runningCompactor{} + // dbMetricsMonitorsMu guards access to dbMetricsMonitors map + dbMetricsMonitorsMu sync.Mutex + dbMetricsMonitors map[string]struct{} +) + +// startCompactorOnce start one compactor per transport. If the interval get smaller on repeated calls, the +// compactor is replaced. A destroy func is returned. If all destroy funcs with the same transport are called, +// the compactor is stopped. +func startCompactorOnce(c storagebackend.TransportConfig, interval time.Duration) (func(), error) { + compactorsMu.Lock() + defer compactorsMu.Unlock() + + key := fmt.Sprintf("%v", c) // gives: {[server1 server2] keyFile certFile caFile} + if compactor, foundBefore := compactors[key]; !foundBefore || compactor.interval > interval { + compactorClient, err := newETCD3Client(c) + if err != nil { + return nil, err + } + + if foundBefore { + // replace compactor + compactor.cancel() + compactor.client.Close() + } else { + // start new compactor + compactor = &runningCompactor{} + compactors[key] = compactor + } + + ctx, cancel := context.WithCancel(context.Background()) + + compactor.interval = interval + compactor.cancel = cancel + compactor.client = compactorClient + + etcd3.StartCompactor(ctx, compactorClient, interval) + } + + compactors[key].refs++ + + return func() { + compactorsMu.Lock() + defer compactorsMu.Unlock() + + compactor := compactors[key] + compactor.refs-- + if compactor.refs == 0 { + compactor.cancel() + compactor.client.Close() + delete(compactors, key) + } + }, nil +} + +func newETCD3Storage(c storagebackend.ConfigForResource, newFunc func() runtime.Object) (storage.Interface, DestroyFunc, error) { + stopCompactor, err := startCompactorOnce(c.Transport, c.CompactionInterval) + if err != nil { + return nil, nil, err + } + + client, err := newETCD3Client(c.Transport) + if err != nil { + stopCompactor() + return nil, nil, err + } + + // decorate the KV instance so we can track etcd latency per request. + client.KV = etcd3.NewETCDLatencyTracker(client.KV) + + stopDBSizeMonitor, err := startDBSizeMonitorPerEndpoint(client, c.DBMetricPollInterval) + if err != nil { + return nil, nil, err + } + + var once sync.Once + destroyFunc := func() { + // we know that storage destroy funcs are called multiple times (due to reuse in subresources). + // Hence, we only destroy once. + // TODO: fix duplicated storage destroy calls higher level + once.Do(func() { + stopCompactor() + stopDBSizeMonitor() + client.Close() + }) + } + transformer := c.Transformer + if transformer == nil { + transformer = identity.NewEncryptCheckTransformer() + } + return etcd3.New(client, c.Codec, newFunc, c.Prefix, c.GroupResource, transformer, c.Paging, c.LeaseManagerConfig), destroyFunc, nil +} + +// startDBSizeMonitorPerEndpoint starts a loop to monitor etcd database size and update the +// corresponding metric etcd_db_total_size_in_bytes for each etcd server endpoint. +func startDBSizeMonitorPerEndpoint(client *clientv3.Client, interval time.Duration) (func(), error) { + if interval == 0 { + return func() {}, nil + } + dbMetricsMonitorsMu.Lock() + defer dbMetricsMonitorsMu.Unlock() + + ctx, cancel := context.WithCancel(context.Background()) + for _, ep := range client.Endpoints() { + if _, found := dbMetricsMonitors[ep]; found { + continue + } + dbMetricsMonitors[ep] = struct{}{} + endpoint := ep + klog.V(4).Infof("Start monitoring storage db size metric for endpoint %s with polling interval %v", endpoint, interval) + go wait.JitterUntilWithContext(ctx, func(context.Context) { + epStatus, err := client.Maintenance.Status(ctx, endpoint) + if err != nil { + klog.V(4).Infof("Failed to get storage db size for ep %s: %v", endpoint, err) + metrics.UpdateEtcdDbSize(endpoint, -1) + } else { + metrics.UpdateEtcdDbSize(endpoint, epStatus.DbSize) + } + }, interval, dbMetricsMonitorJitter, true) + } + + return func() { + cancel() + }, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/factory.go b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/factory.go new file mode 100644 index 0000000000..4c8a409d65 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/factory.go @@ -0,0 +1,63 @@ +/* +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 factory + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/storagebackend" +) + +// DestroyFunc is to destroy any resources used by the storage returned in Create() together. +type DestroyFunc func() + +// Create creates a storage backend based on given config. +func Create(c storagebackend.ConfigForResource, newFunc func() runtime.Object) (storage.Interface, DestroyFunc, error) { + switch c.Type { + case storagebackend.StorageTypeETCD2: + return nil, nil, fmt.Errorf("%s is no longer a supported storage backend", c.Type) + case storagebackend.StorageTypeUnset, storagebackend.StorageTypeETCD3: + return newETCD3Storage(c, newFunc) + default: + return nil, nil, fmt.Errorf("unknown storage type: %s", c.Type) + } +} + +// CreateHealthCheck creates a healthcheck function based on given config. +func CreateHealthCheck(c storagebackend.Config, stopCh <-chan struct{}) (func() error, error) { + switch c.Type { + case storagebackend.StorageTypeETCD2: + return nil, fmt.Errorf("%s is no longer a supported storage backend", c.Type) + case storagebackend.StorageTypeUnset, storagebackend.StorageTypeETCD3: + return newETCD3HealthCheck(c, stopCh) + default: + return nil, fmt.Errorf("unknown storage type: %s", c.Type) + } +} + +func CreateReadyCheck(c storagebackend.Config, stopCh <-chan struct{}) (func() error, error) { + switch c.Type { + case storagebackend.StorageTypeETCD2: + return nil, fmt.Errorf("%s is no longer a supported storage backend", c.Type) + case storagebackend.StorageTypeUnset, storagebackend.StorageTypeETCD3: + return newETCD3ReadyCheck(c, stopCh) + default: + return nil, fmt.Errorf("unknown storage type: %s", c.Type) + } +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/util.go b/vendor/k8s.io/apiserver/pkg/storage/util.go new file mode 100644 index 0000000000..9da8d9713c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/util.go @@ -0,0 +1,81 @@ +/* +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 storage + +import ( + "fmt" + "sync/atomic" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/api/validation/path" + "k8s.io/apimachinery/pkg/runtime" +) + +type SimpleUpdateFunc func(runtime.Object) (runtime.Object, error) + +// SimpleUpdateFunc converts SimpleUpdateFunc into UpdateFunc +func SimpleUpdate(fn SimpleUpdateFunc) UpdateFunc { + return func(input runtime.Object, _ ResponseMeta) (runtime.Object, *uint64, error) { + out, err := fn(input) + return out, nil, err + } +} + +func EverythingFunc(runtime.Object) bool { + return true +} + +func NamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) { + meta, err := meta.Accessor(obj) + if err != nil { + return "", err + } + name := meta.GetName() + if msgs := path.IsValidPathSegmentName(name); len(msgs) != 0 { + return "", fmt.Errorf("invalid name: %v", msgs) + } + return prefix + "/" + meta.GetNamespace() + "/" + name, nil +} + +func NoNamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) { + meta, err := meta.Accessor(obj) + if err != nil { + return "", err + } + name := meta.GetName() + if msgs := path.IsValidPathSegmentName(name); len(msgs) != 0 { + return "", fmt.Errorf("invalid name: %v", msgs) + } + return prefix + "/" + name, nil +} + +// HighWaterMark is a thread-safe object for tracking the maximum value seen +// for some quantity. +type HighWaterMark int64 + +// Update returns true if and only if 'current' is the highest value ever seen. +func (hwm *HighWaterMark) Update(current int64) bool { + for { + old := atomic.LoadInt64((*int64)(hwm)) + if current <= old { + return false + } + if atomic.CompareAndSwapInt64((*int64)(hwm), old, current) { + return true + } + } +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/OWNERS b/vendor/k8s.io/apiserver/pkg/storage/value/OWNERS new file mode 100644 index 0000000000..d2ea8ec60c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/OWNERS @@ -0,0 +1,8 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - sig-auth-encryption-at-rest-approvers +reviewers: + - sig-auth-encryption-at-rest-reviewers +labels: + - sig/auth diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/aes/aes.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/aes/aes.go new file mode 100644 index 0000000000..b26c92e2d5 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/aes/aes.go @@ -0,0 +1,267 @@ +/* +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 aes transforms values for storage at rest using AES-GCM. +package aes + +import ( + "bytes" + "context" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/binary" + "errors" + "fmt" + "io" + "sync/atomic" + "time" + + "k8s.io/apiserver/pkg/storage/value" + "k8s.io/klog/v2" +) + +type gcm struct { + aead cipher.AEAD + nonceFunc func([]byte) error +} + +// NewGCMTransformer takes the given block cipher and performs encryption and decryption on the given data. +// It implements AEAD encryption of the provided values given a cipher.Block algorithm. +// The authenticated data provided as part of the value.Context method must match when the same +// value is set to and loaded from storage. In order to ensure that values cannot be copied by +// an attacker from a location under their control, use characteristics of the storage location +// (such as the etcd key) as part of the authenticated data. +// +// Because this mode requires a generated IV and IV reuse is a known weakness of AES-GCM, keys +// must be rotated before a birthday attack becomes feasible. NIST SP 800-38D +// (http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf) recommends using the same +// key with random 96-bit nonces (the default nonce length) no more than 2^32 times, and +// therefore transformers using this implementation *must* ensure they allow for frequent key +// rotation. Future work should include investigation of AES-GCM-SIV as an alternative to +// random nonces. +func NewGCMTransformer(block cipher.Block) (value.Transformer, error) { + aead, err := newGCM(block) + if err != nil { + return nil, err + } + + return &gcm{aead: aead, nonceFunc: randomNonce}, nil +} + +// NewGCMTransformerWithUniqueKeyUnsafe is the same as NewGCMTransformer but is unsafe for general +// use because it makes assumptions about the key underlying the block cipher. Specifically, +// it uses a 96-bit nonce where the first 32 bits are random data and the remaining 64 bits are +// a monotonically incrementing atomic counter. This means that the key must be randomly generated +// on process startup and must never be used for encryption outside the lifetime of the process. +// Unlike NewGCMTransformer, this function is immune to the birthday attack and thus the key can +// be used for 2^64-1 writes without rotation. Furthermore, cryptographic wear out of AES-GCM with +// a sequential nonce occurs after 2^64 encryptions, which is not a concern for our use cases. +// Even if that occurs, the nonce counter would overflow and crash the process. We have no concerns +// around plaintext length because all stored items are small (less than 2 MB). To prevent the +// chance of the block cipher being accidentally re-used, it is not taken in as input. Instead, +// a new random key is generated and returned on every invocation of this function. This key is +// used as the input to the block cipher. If the key is stored and retrieved at a later point, +// it can be passed to NewGCMTransformer(aes.NewCipher(key)) to construct a transformer capable +// of decrypting values encrypted by this transformer (that transformer must not be used for encryption). +func NewGCMTransformerWithUniqueKeyUnsafe() (value.Transformer, []byte, error) { + key, err := generateKey(32) + if err != nil { + return nil, nil, err + } + block, err := aes.NewCipher(key) + if err != nil { + return nil, nil, err + } + + nonceGen := &nonceGenerator{ + // we start the nonce counter at one billion so that we are + // guaranteed to detect rollover across different go routines + zero: 1_000_000_000, + fatal: die, + } + nonceGen.nonce.Add(nonceGen.zero) + + transformer, err := newGCMTransformerWithUniqueKeyUnsafe(block, nonceGen) + if err != nil { + return nil, nil, err + } + return transformer, key, nil +} + +func newGCMTransformerWithUniqueKeyUnsafe(block cipher.Block, nonceGen *nonceGenerator) (value.Transformer, error) { + aead, err := newGCM(block) + if err != nil { + return nil, err + } + + nonceFunc := func(b []byte) error { + // we only need 8 bytes to store our 64 bit incrementing nonce + // instead of leaving the unused bytes as zeros, set those to random bits + // this mostly protects us from weird edge cases like a VM restore that rewinds our atomic counter + randNonceSize := len(b) - 8 + + if err := randomNonce(b[:randNonceSize]); err != nil { + return err + } + + nonceGen.next(b[randNonceSize:]) + + return nil + } + + return &gcm{aead: aead, nonceFunc: nonceFunc}, nil +} + +func newGCM(block cipher.Block) (cipher.AEAD, error) { + aead, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + if nonceSize := aead.NonceSize(); nonceSize != 12 { // all data in etcd will be broken if this ever changes + return nil, fmt.Errorf("crypto/cipher.NewGCM returned unexpected nonce size: %d", nonceSize) + } + return aead, nil +} + +func randomNonce(b []byte) error { + _, err := rand.Read(b) + return err +} + +type nonceGenerator struct { + // even at one million encryptions per second, this counter is enough for half a million years + // using this struct avoids alignment bugs: https://pkg.go.dev/sync/atomic#pkg-note-BUG + nonce atomic.Uint64 + zero uint64 + fatal func(msg string) +} + +func (n *nonceGenerator) next(b []byte) { + incrementingNonce := n.nonce.Add(1) + if incrementingNonce <= n.zero { + // this should never happen, and is unrecoverable if it does + n.fatal("aes-gcm detected nonce overflow - cryptographic wear out has occurred") + } + binary.LittleEndian.PutUint64(b, incrementingNonce) +} + +func die(msg string) { + // nolint:logcheck // we want the stack traces, log flushing, and process exiting logic from FatalDepth + klog.FatalDepth(1, msg) +} + +// generateKey generates a random key using system randomness. +func generateKey(length int) (key []byte, err error) { + defer func(start time.Time) { + value.RecordDataKeyGeneration(start, err) + }(time.Now()) + key = make([]byte, length) + if _, err = rand.Read(key); err != nil { + return nil, err + } + + return key, nil +} + +func (t *gcm) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { + nonceSize := t.aead.NonceSize() + if len(data) < nonceSize { + return nil, false, errors.New("the stored data was shorter than the required size") + } + result, err := t.aead.Open(nil, data[:nonceSize], data[nonceSize:], dataCtx.AuthenticatedData()) + return result, false, err +} + +func (t *gcm) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) { + nonceSize := t.aead.NonceSize() + result := make([]byte, nonceSize+t.aead.Overhead()+len(data)) + + if err := t.nonceFunc(result[:nonceSize]); err != nil { + return nil, fmt.Errorf("failed to write nonce for AES-GCM: %w", err) + } + + cipherText := t.aead.Seal(result[nonceSize:nonceSize], result[:nonceSize], data, dataCtx.AuthenticatedData()) + return result[:nonceSize+len(cipherText)], nil +} + +// cbc implements encryption at rest of the provided values given a cipher.Block algorithm. +type cbc struct { + block cipher.Block +} + +// NewCBCTransformer takes the given block cipher and performs encryption and decryption on the given +// data. +func NewCBCTransformer(block cipher.Block) value.Transformer { + return &cbc{block: block} +} + +var ( + errInvalidBlockSize = errors.New("the stored data is not a multiple of the block size") + errInvalidPKCS7Data = errors.New("invalid PKCS7 data (empty or not padded)") + errInvalidPKCS7Padding = errors.New("invalid padding on input") +) + +func (t *cbc) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { + blockSize := aes.BlockSize + if len(data) < blockSize { + return nil, false, errors.New("the stored data was shorter than the required size") + } + iv := data[:blockSize] + data = data[blockSize:] + + if len(data)%blockSize != 0 { + return nil, false, errInvalidBlockSize + } + + result := make([]byte, len(data)) + copy(result, data) + mode := cipher.NewCBCDecrypter(t.block, iv) + mode.CryptBlocks(result, result) + + // remove and verify PKCS#7 padding for CBC + c := result[len(result)-1] + paddingSize := int(c) + size := len(result) - paddingSize + if paddingSize == 0 || paddingSize > len(result) { + return nil, false, errInvalidPKCS7Data + } + for i := 0; i < paddingSize; i++ { + if result[size+i] != c { + return nil, false, errInvalidPKCS7Padding + } + } + + return result[:size], false, nil +} + +func (t *cbc) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) { + blockSize := aes.BlockSize + paddingSize := blockSize - (len(data) % blockSize) + result := make([]byte, blockSize+len(data)+paddingSize) + iv := result[:blockSize] + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + return nil, errors.New("unable to read sufficient random bytes") + } + copy(result[blockSize:], data) + + // add PKCS#7 padding for CBC + copy(result[blockSize+len(data):], bytes.Repeat([]byte{byte(paddingSize)}, paddingSize)) + + mode := cipher.NewCBCEncrypter(t.block, iv) + mode.CryptBlocks(result[blockSize:], result[blockSize:]) + return result, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/envelope.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/envelope.go new file mode 100644 index 0000000000..4bb18ee8ba --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/envelope.go @@ -0,0 +1,202 @@ +/* +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 envelope transforms values for storage at rest using a Envelope provider +package envelope + +import ( + "context" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/base64" + "fmt" + "time" + + "k8s.io/apiserver/pkg/storage/value" + "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics" + "k8s.io/utils/lru" + + "golang.org/x/crypto/cryptobyte" +) + +func init() { + value.RegisterMetrics() + metrics.RegisterMetrics() +} + +// Service allows encrypting and decrypting data using an external Key Management Service. +type Service interface { + // Decrypt a given bytearray to obtain the original data as bytes. + Decrypt(data []byte) ([]byte, error) + // Encrypt bytes to a ciphertext. + Encrypt(data []byte) ([]byte, error) +} + +type envelopeTransformer struct { + envelopeService Service + + // transformers is a thread-safe LRU cache which caches decrypted DEKs indexed by their encrypted form. + transformers *lru.Cache + + // baseTransformerFunc creates a new transformer for encrypting the data with the DEK. + baseTransformerFunc func(cipher.Block) (value.Transformer, error) + + cacheSize int + cacheEnabled bool +} + +// NewEnvelopeTransformer returns a transformer which implements a KEK-DEK based envelope encryption scheme. +// It uses envelopeService to encrypt and decrypt DEKs. Respective DEKs (in encrypted form) are prepended to +// the data items they encrypt. A cache (of size cacheSize) is maintained to store the most recently +// used decrypted DEKs in memory. +func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransformerFunc func(cipher.Block) (value.Transformer, error)) value.Transformer { + var ( + cache *lru.Cache + ) + + if cacheSize > 0 { + cache = lru.New(cacheSize) + } + return &envelopeTransformer{ + envelopeService: envelopeService, + transformers: cache, + baseTransformerFunc: baseTransformerFunc, + cacheEnabled: cacheSize > 0, + cacheSize: cacheSize, + } +} + +// TransformFromStorage decrypts data encrypted by this transformer using envelope encryption. +func (t *envelopeTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { + metrics.RecordArrival(metrics.FromStorageLabel, time.Now()) + + // Read the 16 bit length-of-DEK encoded at the start of the encrypted DEK. 16 bits can + // represent a maximum key length of 65536 bytes. We are using a 256 bit key, whose + // length cannot fit in 8 bits (1 byte). Thus, we use 16 bits (2 bytes) to store the length. + var encKey cryptobyte.String + s := cryptobyte.String(data) + if ok := s.ReadUint16LengthPrefixed(&encKey); !ok { + return nil, false, fmt.Errorf("invalid data encountered by envelope transformer: failed to read uint16 length prefixed data") + } + + encData := []byte(s) + + // Look up the decrypted DEK from cache or Envelope. + transformer := t.getTransformer(encKey) + if transformer == nil { + if t.cacheEnabled { + value.RecordCacheMiss() + } + key, err := t.envelopeService.Decrypt(encKey) + if err != nil { + // Do NOT wrap this err using fmt.Errorf() or similar functions + // because this gRPC status error has useful error code when + // record the metric. + return nil, false, err + } + + transformer, err = t.addTransformer(encKey, key) + if err != nil { + return nil, false, err + } + } + + return transformer.TransformFromStorage(ctx, encData, dataCtx) +} + +// TransformToStorage encrypts data to be written to disk using envelope encryption. +func (t *envelopeTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) { + metrics.RecordArrival(metrics.ToStorageLabel, time.Now()) + newKey, err := generateKey(32) + if err != nil { + return nil, err + } + + encKey, err := t.envelopeService.Encrypt(newKey) + if err != nil { + // Do NOT wrap this err using fmt.Errorf() or similar functions + // because this gRPC status error has useful error code when + // record the metric. + return nil, err + } + + transformer, err := t.addTransformer(encKey, newKey) + if err != nil { + return nil, err + } + + result, err := transformer.TransformToStorage(ctx, data, dataCtx) + if err != nil { + return nil, err + } + // Append the length of the encrypted DEK as the first 2 bytes. + b := cryptobyte.NewBuilder(nil) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes([]byte(encKey)) + }) + b.AddBytes(result) + + return b.Bytes() +} + +var _ value.Transformer = &envelopeTransformer{} + +// addTransformer inserts a new transformer to the Envelope cache of DEKs for future reads. +func (t *envelopeTransformer) addTransformer(encKey []byte, key []byte) (value.Transformer, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + transformer, err := t.baseTransformerFunc(block) + if err != nil { + return nil, err + } + + // Use base64 of encKey as the key into the cache because hashicorp/golang-lru + // cannot hash []uint8. + if t.cacheEnabled { + t.transformers.Add(base64.StdEncoding.EncodeToString(encKey), transformer) + metrics.RecordDekCacheFillPercent(float64(t.transformers.Len()) / float64(t.cacheSize)) + } + return transformer, nil +} + +// getTransformer fetches the transformer corresponding to encKey from cache, if it exists. +func (t *envelopeTransformer) getTransformer(encKey []byte) value.Transformer { + if !t.cacheEnabled { + return nil + } + + _transformer, found := t.transformers.Get(base64.StdEncoding.EncodeToString(encKey)) + if found { + return _transformer.(value.Transformer) + } + return nil +} + +// generateKey generates a random key using system randomness. +func generateKey(length int) (key []byte, err error) { + defer func(start time.Time) { + value.RecordDataKeyGeneration(start, err) + }(time.Now()) + key = make([]byte, length) + if _, err = rand.Read(key); err != nil { + return nil, err + } + + return key, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go new file mode 100644 index 0000000000..b2a5fd145c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go @@ -0,0 +1,162 @@ +/* +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 envelope transforms values for storage at rest using a Envelope provider +package envelope + +import ( + "context" + "fmt" + "net" + "sync" + "time" + + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/klog/v2" + kmsapi "k8s.io/kms/apis/v1beta1" + "k8s.io/kms/pkg/util" +) + +const ( + // unixProtocol is the only supported protocol for remote KMS provider. + unixProtocol = "unix" + // Current version for the protocol interface definition. + kmsapiVersion = "v1beta1" + + versionErrorf = "KMS provider api version %s is not supported, only %s is supported now" +) + +// The gRPC implementation for envelope.Service. +type gRPCService struct { + kmsClient kmsapi.KeyManagementServiceClient + connection *grpc.ClientConn + callTimeout time.Duration + mux sync.RWMutex + versionChecked bool +} + +// NewGRPCService returns an envelope.Service which use gRPC to communicate the remote KMS provider. +func NewGRPCService(ctx context.Context, endpoint string, callTimeout time.Duration) (Service, error) { + klog.V(4).InfoS("Configure KMS provider", "endpoint", endpoint) + + addr, err := util.ParseEndpoint(endpoint) + if err != nil { + return nil, err + } + + s := &gRPCService{callTimeout: callTimeout} + s.connection, err = grpc.Dial( + addr, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithUnaryInterceptor(s.interceptor), + grpc.WithDefaultCallOptions(grpc.WaitForReady(true)), + grpc.WithContextDialer( + func(context.Context, string) (net.Conn, error) { + // Ignoring addr and timeout arguments: + // addr - comes from the closure + c, err := net.DialUnix(unixProtocol, nil, &net.UnixAddr{Name: addr}) + if err != nil { + klog.ErrorS(err, "failed to create connection to unix socket", "addr", addr) + } else { + klog.V(4).InfoS("Successfully dialed Unix socket", "addr", addr) + } + return c, err + })) + + if err != nil { + return nil, fmt.Errorf("failed to create connection to %s, error: %v", endpoint, err) + } + + s.kmsClient = kmsapi.NewKeyManagementServiceClient(s.connection) + + go func() { + defer utilruntime.HandleCrash() + + <-ctx.Done() + _ = s.connection.Close() + }() + + return s, nil +} + +func (g *gRPCService) checkAPIVersion(ctx context.Context) error { + g.mux.Lock() + defer g.mux.Unlock() + + if g.versionChecked { + return nil + } + + request := &kmsapi.VersionRequest{Version: kmsapiVersion} + response, err := g.kmsClient.Version(ctx, request) + if err != nil { + return fmt.Errorf("failed get version from remote KMS provider: %v", err) + } + if response.Version != kmsapiVersion { + return fmt.Errorf(versionErrorf, response.Version, kmsapiVersion) + } + g.versionChecked = true + + klog.V(4).InfoS("KMS provider api version verified", "version", response.Version) + return nil +} + +// Decrypt a given data string to obtain the original byte data. +func (g *gRPCService) Decrypt(cipher []byte) ([]byte, error) { + ctx, cancel := context.WithTimeout(context.Background(), g.callTimeout) + defer cancel() + + request := &kmsapi.DecryptRequest{Cipher: cipher, Version: kmsapiVersion} + response, err := g.kmsClient.Decrypt(ctx, request) + if err != nil { + return nil, err + } + return response.Plain, nil +} + +// Encrypt bytes to a string ciphertext. +func (g *gRPCService) Encrypt(plain []byte) ([]byte, error) { + ctx, cancel := context.WithTimeout(context.Background(), g.callTimeout) + defer cancel() + + request := &kmsapi.EncryptRequest{Plain: plain, Version: kmsapiVersion} + response, err := g.kmsClient.Encrypt(ctx, request) + if err != nil { + return nil, err + } + return response.Cipher, nil +} + +func (g *gRPCService) interceptor( + ctx context.Context, + method string, + req interface{}, + reply interface{}, + cc *grpc.ClientConn, + invoker grpc.UnaryInvoker, + opts ...grpc.CallOption, +) error { + if !kmsapi.IsVersionCheckMethod(method) { + if err := g.checkAPIVersion(ctx); err != nil { + return err + } + } + + return invoker(ctx, method, req, reply, cc, opts...) +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/cache.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/cache.go new file mode 100644 index 0000000000..3c1fbbf8a3 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/cache.go @@ -0,0 +1,108 @@ +/* +Copyright 2023 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 kmsv2 transforms values for storage at rest using a Envelope v2 provider +package kmsv2 + +import ( + "context" + "crypto/sha256" + "hash" + "sync" + "time" + "unsafe" + + utilcache "k8s.io/apimachinery/pkg/util/cache" + "k8s.io/apiserver/pkg/storage/value" + "k8s.io/utils/clock" +) + +// prevent decryptTransformer from drifting from value.Transformer +var _ decryptTransformer = value.Transformer(nil) + +// decryptTransformer is the decryption subset of value.Transformer. +// this exists purely to statically enforce that transformers placed in the cache are not used for encryption. +// this is relevant in the context of nonce collision since transformers that are created +// from encrypted DEKs retrieved from etcd cannot maintain their nonce counter state. +type decryptTransformer interface { + TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) (out []byte, stale bool, err error) +} + +type simpleCache struct { + cache *utilcache.Expiring + ttl time.Duration + // hashPool is a per cache pool of hash.Hash (to avoid allocations from building the Hash) + // SHA-256 is used to prevent collisions + hashPool *sync.Pool +} + +func newSimpleCache(clock clock.Clock, ttl time.Duration) *simpleCache { + return &simpleCache{ + cache: utilcache.NewExpiringWithClock(clock), + ttl: ttl, + hashPool: &sync.Pool{ + New: func() interface{} { + return sha256.New() + }, + }, + } +} + +// given a key, return the transformer, or nil if it does not exist in the cache +func (c *simpleCache) get(key []byte) decryptTransformer { + record, ok := c.cache.Get(c.keyFunc(key)) + if !ok { + return nil + } + return record.(decryptTransformer) +} + +// set caches the record for the key +func (c *simpleCache) set(key []byte, transformer decryptTransformer) { + if len(key) == 0 { + panic("key must not be empty") + } + if transformer == nil { + panic("transformer must not be nil") + } + c.cache.Set(c.keyFunc(key), transformer, c.ttl) +} + +// keyFunc generates a string key by hashing the inputs. +// This lowers the memory requirement of the cache. +func (c *simpleCache) keyFunc(s []byte) string { + h := c.hashPool.Get().(hash.Hash) + h.Reset() + + if _, err := h.Write(s); err != nil { + panic(err) // Write() on hash never fails + } + key := toString(h.Sum(nil)) // skip base64 encoding to save an allocation + c.hashPool.Put(h) + + return key +} + +// toString performs unholy acts to avoid allocations +func toString(b []byte) string { + // unsafe.SliceData relies on cap whereas we want to rely on len + if len(b) == 0 { + return "" + } + // Copied from go 1.20.1 strings.Builder.String + // https://github.com/golang/go/blob/202a1a57064127c3f19d96df57b9f9586145e21c/src/strings/builder.go#L48 + return unsafe.String(unsafe.SliceData(b), len(b)) +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go new file mode 100644 index 0000000000..43ba22d65e --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go @@ -0,0 +1,422 @@ +/* +Copyright 2022 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 kmsv2 transforms values for storage at rest using a Envelope v2 provider +package kmsv2 + +import ( + "context" + "crypto/aes" + "fmt" + "sort" + "time" + "unsafe" + + "github.com/gogo/protobuf/proto" + "golang.org/x/crypto/cryptobyte" + + utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/apimachinery/pkg/util/validation" + "k8s.io/apimachinery/pkg/util/validation/field" + genericapirequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/storage/value" + aestransformer "k8s.io/apiserver/pkg/storage/value/encrypt/aes" + kmstypes "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2" + "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics" + "k8s.io/klog/v2" + kmsservice "k8s.io/kms/pkg/service" + "k8s.io/utils/clock" +) + +func init() { + value.RegisterMetrics() + metrics.RegisterMetrics() +} + +const ( + // KMSAPIVersion is the version of the KMS API. + KMSAPIVersion = "v2beta1" + // annotationsMaxSize is the maximum size of the annotations. + annotationsMaxSize = 32 * 1024 // 32 kB + // KeyIDMaxSize is the maximum size of the keyID. + KeyIDMaxSize = 1 * 1024 // 1 kB + // encryptedDEKMaxSize is the maximum size of the encrypted DEK. + encryptedDEKMaxSize = 1 * 1024 // 1 kB + // cacheTTL is the default time-to-live for the cache entry. + // this allows the cache to grow to an infinite size for up to a day. + // this is meant as a temporary solution until the cache is re-written to not have a TTL. + // there is unlikely to be any meaningful memory impact on the server + // because the cache will likely never have more than a few thousand entries + // and each entry is roughly ~200 bytes in size. with DEK reuse + // and no storage migration, the number of entries in this cache + // would be approximated by unique key IDs used by the KMS plugin + // combined with the number of server restarts. If storage migration + // is performed after key ID changes, and the number of restarts + // is limited, this cache size may be as small as the number of API + // servers in use (once old entries expire out from the TTL). + cacheTTL = 24 * time.Hour + // error code + errKeyIDOKCode ErrCodeKeyID = "ok" + errKeyIDEmptyCode ErrCodeKeyID = "empty" + errKeyIDTooLongCode ErrCodeKeyID = "too_long" +) + +// NowFunc is exported so tests can override it. +var NowFunc = time.Now + +type StateFunc func() (State, error) +type ErrCodeKeyID string + +type State struct { + Transformer value.Transformer + EncryptedDEK []byte + KeyID string + Annotations map[string][]byte + + UID string + + ExpirationTimestamp time.Time + + // CacheKey is the key used to cache the DEK in transformer.cache. + CacheKey []byte +} + +func (s *State) ValidateEncryptCapability() error { + if now := NowFunc(); now.After(s.ExpirationTimestamp) { + return fmt.Errorf("EDEK with keyID %q expired at %s (current time is %s)", + s.KeyID, s.ExpirationTimestamp.Format(time.RFC3339), now.Format(time.RFC3339)) + } + return nil +} + +type envelopeTransformer struct { + envelopeService kmsservice.Service + providerName string + stateFunc StateFunc + + // cache is a thread-safe expiring lru cache which caches decrypted DEKs indexed by their encrypted form. + cache *simpleCache +} + +// NewEnvelopeTransformer returns a transformer which implements a KEK-DEK based envelope encryption scheme. +// It uses envelopeService to encrypt and decrypt DEKs. Respective DEKs (in encrypted form) are prepended to +// the data items they encrypt. +func NewEnvelopeTransformer(envelopeService kmsservice.Service, providerName string, stateFunc StateFunc) value.Transformer { + return newEnvelopeTransformerWithClock(envelopeService, providerName, stateFunc, cacheTTL, clock.RealClock{}) +} + +func newEnvelopeTransformerWithClock(envelopeService kmsservice.Service, providerName string, stateFunc StateFunc, cacheTTL time.Duration, clock clock.Clock) value.Transformer { + return &envelopeTransformer{ + envelopeService: envelopeService, + providerName: providerName, + stateFunc: stateFunc, + cache: newSimpleCache(clock, cacheTTL), + } +} + +// TransformFromStorage decrypts data encrypted by this transformer using envelope encryption. +func (t *envelopeTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { + // Deserialize the EncryptedObject from the data. + encryptedObject, err := t.doDecode(data) + if err != nil { + return nil, false, err + } + + // TODO: consider marking state.EncryptedDEK != encryptedObject.EncryptedDEK as a stale read to support DEK defragmentation + // at a minimum we should have a metric that helps the user understand if DEK fragmentation is high + state, err := t.stateFunc() // no need to call state.ValidateEncryptCapability on reads + if err != nil { + return nil, false, err + } + + encryptedObjectCacheKey, err := generateCacheKey(encryptedObject.EncryptedDEK, encryptedObject.KeyID, encryptedObject.Annotations) + if err != nil { + return nil, false, err + } + + // Look up the decrypted DEK from cache first + transformer := t.cache.get(encryptedObjectCacheKey) + + // fallback to the envelope service if we do not have the transformer locally + if transformer == nil { + value.RecordCacheMiss() + + requestInfo := getRequestInfoFromContext(ctx) + uid := string(uuid.NewUUID()) + klog.V(6).InfoS("decrypting content using envelope service", "uid", uid, "key", string(dataCtx.AuthenticatedData()), + "group", requestInfo.APIGroup, "version", requestInfo.APIVersion, "resource", requestInfo.Resource, "subresource", requestInfo.Subresource, + "verb", requestInfo.Verb, "namespace", requestInfo.Namespace, "name", requestInfo.Name) + + key, err := t.envelopeService.Decrypt(ctx, uid, &kmsservice.DecryptRequest{ + Ciphertext: encryptedObject.EncryptedDEK, + KeyID: encryptedObject.KeyID, + Annotations: encryptedObject.Annotations, + }) + if err != nil { + return nil, false, fmt.Errorf("failed to decrypt DEK, error: %w", err) + } + + transformer, err = t.addTransformerForDecryption(encryptedObjectCacheKey, key) + if err != nil { + return nil, false, err + } + } + metrics.RecordKeyID(metrics.FromStorageLabel, t.providerName, encryptedObject.KeyID) + + out, stale, err := transformer.TransformFromStorage(ctx, encryptedObject.EncryptedData, dataCtx) + if err != nil { + return nil, false, err + } + + // data is considered stale if the key ID does not match our current write transformer + return out, stale || encryptedObject.KeyID != state.KeyID, nil + +} + +// TransformToStorage encrypts data to be written to disk using envelope encryption. +func (t *envelopeTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) { + state, err := t.stateFunc() + if err != nil { + return nil, err + } + if err := state.ValidateEncryptCapability(); err != nil { + return nil, err + } + + // this prevents a cache miss every time the DEK rotates + // this has the side benefit of causing the cache to perform a GC + // TODO see if we can do this inside the stateFunc control loop + // TODO(aramase): Add metrics for cache fill percentage with custom cache implementation. + t.cache.set(state.CacheKey, state.Transformer) + + requestInfo := getRequestInfoFromContext(ctx) + klog.V(6).InfoS("encrypting content using DEK", "uid", state.UID, "key", string(dataCtx.AuthenticatedData()), + "group", requestInfo.APIGroup, "version", requestInfo.APIVersion, "resource", requestInfo.Resource, "subresource", requestInfo.Subresource, + "verb", requestInfo.Verb, "namespace", requestInfo.Namespace, "name", requestInfo.Name) + + result, err := state.Transformer.TransformToStorage(ctx, data, dataCtx) + if err != nil { + return nil, err + } + + metrics.RecordKeyID(metrics.ToStorageLabel, t.providerName, state.KeyID) + + encObject := &kmstypes.EncryptedObject{ + KeyID: state.KeyID, + EncryptedDEK: state.EncryptedDEK, + EncryptedData: result, + Annotations: state.Annotations, + } + + // Serialize the EncryptedObject to a byte array. + return t.doEncode(encObject) +} + +// addTransformerForDecryption inserts a new transformer to the Envelope cache of DEKs for future reads. +func (t *envelopeTransformer) addTransformerForDecryption(cacheKey []byte, key []byte) (decryptTransformer, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + // this is compatible with NewGCMTransformerWithUniqueKeyUnsafe for decryption + // it would use random nonces for encryption but we never do that + transformer, err := aestransformer.NewGCMTransformer(block) + if err != nil { + return nil, err + } + // TODO(aramase): Add metrics for cache fill percentage with custom cache implementation. + t.cache.set(cacheKey, transformer) + return transformer, nil +} + +// doEncode encodes the EncryptedObject to a byte array. +func (t *envelopeTransformer) doEncode(request *kmstypes.EncryptedObject) ([]byte, error) { + if err := validateEncryptedObject(request); err != nil { + return nil, err + } + return proto.Marshal(request) +} + +// doDecode decodes the byte array to an EncryptedObject. +func (t *envelopeTransformer) doDecode(originalData []byte) (*kmstypes.EncryptedObject, error) { + o := &kmstypes.EncryptedObject{} + if err := proto.Unmarshal(originalData, o); err != nil { + return nil, err + } + // validate the EncryptedObject + if err := validateEncryptedObject(o); err != nil { + return nil, err + } + + return o, nil +} + +func GenerateTransformer(ctx context.Context, uid string, envelopeService kmsservice.Service) (value.Transformer, *kmsservice.EncryptResponse, []byte, error) { + transformer, newKey, err := aestransformer.NewGCMTransformerWithUniqueKeyUnsafe() + if err != nil { + return nil, nil, nil, err + } + + klog.V(6).InfoS("encrypting content using envelope service", "uid", uid) + + resp, err := envelopeService.Encrypt(ctx, uid, newKey) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to encrypt DEK, error: %w", err) + } + + if err := validateEncryptedObject(&kmstypes.EncryptedObject{ + KeyID: resp.KeyID, + EncryptedDEK: resp.Ciphertext, + EncryptedData: []byte{0}, // any non-empty value to pass validation + Annotations: resp.Annotations, + }); err != nil { + return nil, nil, nil, err + } + + cacheKey, err := generateCacheKey(resp.Ciphertext, resp.KeyID, resp.Annotations) + if err != nil { + return nil, nil, nil, err + } + + return transformer, resp, cacheKey, nil +} + +func validateEncryptedObject(o *kmstypes.EncryptedObject) error { + if o == nil { + return fmt.Errorf("encrypted object is nil") + } + if len(o.EncryptedData) == 0 { + return fmt.Errorf("encrypted data is empty") + } + if err := validateEncryptedDEK(o.EncryptedDEK); err != nil { + return fmt.Errorf("failed to validate encrypted DEK: %w", err) + } + if _, err := ValidateKeyID(o.KeyID); err != nil { + return fmt.Errorf("failed to validate key id: %w", err) + } + if err := validateAnnotations(o.Annotations); err != nil { + return fmt.Errorf("failed to validate annotations: %w", err) + } + return nil +} + +// validateEncryptedDEK tests the following: +// 1. The encrypted DEK is not empty. +// 2. The size of encrypted DEK is less than 1 kB. +func validateEncryptedDEK(encryptedDEK []byte) error { + if len(encryptedDEK) == 0 { + return fmt.Errorf("encrypted DEK is empty") + } + if len(encryptedDEK) > encryptedDEKMaxSize { + return fmt.Errorf("encrypted DEK is %d bytes, which exceeds the max size of %d", len(encryptedDEK), encryptedDEKMaxSize) + } + return nil +} + +// validateAnnotations tests the following: +// 1. checks if the annotation key is fully qualified +// 2. The size of annotations keys + values is less than 32 kB. +func validateAnnotations(annotations map[string][]byte) error { + var errs []error + var totalSize uint64 + for k, v := range annotations { + if fieldErr := validation.IsFullyQualifiedDomainName(field.NewPath("annotations"), k); fieldErr != nil { + errs = append(errs, fieldErr.ToAggregate()) + } + totalSize += uint64(len(k)) + uint64(len(v)) + } + if totalSize > annotationsMaxSize { + errs = append(errs, fmt.Errorf("total size of annotations is %d, which exceeds the max size of %d", totalSize, annotationsMaxSize)) + } + return utilerrors.NewAggregate(errs) +} + +// ValidateKeyID tests the following: +// 1. The keyID is not empty. +// 2. The size of keyID is less than 1 kB. +func ValidateKeyID(keyID string) (ErrCodeKeyID, error) { + if len(keyID) == 0 { + return errKeyIDEmptyCode, fmt.Errorf("keyID is empty") + } + if len(keyID) > KeyIDMaxSize { + return errKeyIDTooLongCode, fmt.Errorf("keyID is %d bytes, which exceeds the max size of %d", len(keyID), KeyIDMaxSize) + } + return errKeyIDOKCode, nil +} + +func getRequestInfoFromContext(ctx context.Context) *genericapirequest.RequestInfo { + if reqInfo, found := genericapirequest.RequestInfoFrom(ctx); found { + return reqInfo + } + return &genericapirequest.RequestInfo{} +} + +// generateCacheKey returns a key for the cache. +// The key is a concatenation of: +// 1. encryptedDEK +// 2. keyID +// 3. length of annotations +// 4. annotations (sorted by key) - each annotation is a concatenation of: +// a. annotation key +// b. annotation value +func generateCacheKey(encryptedDEK []byte, keyID string, annotations map[string][]byte) ([]byte, error) { + // TODO(aramase): use sync pool buffer to avoid allocations + b := cryptobyte.NewBuilder(nil) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(encryptedDEK) + }) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(toBytes(keyID)) + }) + if len(annotations) == 0 { + return b.Bytes() + } + + // add the length of annotations to the cache key + b.AddUint32(uint32(len(annotations))) + + // Sort the annotations by key. + keys := make([]string, 0, len(annotations)) + for k := range annotations { + k := k + keys = append(keys, k) + } + sort.Strings(keys) + for _, k := range keys { + // The maximum size of annotations is annotationsMaxSize (32 kB) so we can safely + // assume that the length of the key and value will fit in a uint16. + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(toBytes(k)) + }) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(annotations[k]) + }) + } + + return b.Bytes() +} + +// toBytes performs unholy acts to avoid allocations +func toBytes(s string) []byte { + // unsafe.StringData is unspecified for the empty string, so we provide a strict interpretation + if len(s) == 0 { + return nil + } + // Copied from go 1.20.1 os.File.WriteString + // https://github.com/golang/go/blob/202a1a57064127c3f19d96df57b9f9586145e21c/src/os/file.go#L246 + return unsafe.Slice(unsafe.StringData(s), len(s)) +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go new file mode 100644 index 0000000000..67f7bc79e1 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go @@ -0,0 +1,153 @@ +/* +Copyright 2022 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 kmsv2 transforms values for storage at rest using a Envelope provider +package kmsv2 + +import ( + "context" + "fmt" + "net" + "time" + + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics" + "k8s.io/klog/v2" + kmsapi "k8s.io/kms/apis/v2" + kmsservice "k8s.io/kms/pkg/service" + "k8s.io/kms/pkg/util" +) + +const ( + // unixProtocol is the only supported protocol for remote KMS provider. + unixProtocol = "unix" +) + +// The gRPC implementation for envelope.Service. +type gRPCService struct { + kmsClient kmsapi.KeyManagementServiceClient + connection *grpc.ClientConn + callTimeout time.Duration +} + +// NewGRPCService returns an envelope.Service which use gRPC to communicate the remote KMS provider. +func NewGRPCService(ctx context.Context, endpoint, providerName string, callTimeout time.Duration) (kmsservice.Service, error) { + klog.V(4).InfoS("Configure KMS provider", "endpoint", endpoint) + + addr, err := util.ParseEndpoint(endpoint) + if err != nil { + return nil, err + } + + s := &gRPCService{callTimeout: callTimeout} + s.connection, err = grpc.Dial( + addr, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithDefaultCallOptions(grpc.WaitForReady(true)), + grpc.WithContextDialer( + func(context.Context, string) (net.Conn, error) { + // Ignoring addr and timeout arguments: + // addr - comes from the closure + c, err := net.DialUnix(unixProtocol, nil, &net.UnixAddr{Name: addr}) + if err != nil { + klog.ErrorS(err, "failed to create connection to unix socket", "addr", addr) + } else { + klog.V(4).InfoS("Successfully dialed Unix socket", "addr", addr) + } + return c, err + }), + grpc.WithChainUnaryInterceptor(recordMetricsInterceptor(providerName)), + ) + + if err != nil { + return nil, fmt.Errorf("failed to create connection to %s, error: %v", endpoint, err) + } + + s.kmsClient = kmsapi.NewKeyManagementServiceClient(s.connection) + + go func() { + defer utilruntime.HandleCrash() + + <-ctx.Done() + _ = s.connection.Close() + }() + + return s, nil +} + +// Decrypt a given data string to obtain the original byte data. +func (g *gRPCService) Decrypt(ctx context.Context, uid string, req *kmsservice.DecryptRequest) ([]byte, error) { + ctx, cancel := context.WithTimeout(ctx, g.callTimeout) + defer cancel() + + request := &kmsapi.DecryptRequest{ + Ciphertext: req.Ciphertext, + Uid: uid, + KeyId: req.KeyID, + Annotations: req.Annotations, + } + response, err := g.kmsClient.Decrypt(ctx, request) + if err != nil { + return nil, err + } + return response.Plaintext, nil +} + +// Encrypt bytes to a string ciphertext. +func (g *gRPCService) Encrypt(ctx context.Context, uid string, plaintext []byte) (*kmsservice.EncryptResponse, error) { + ctx, cancel := context.WithTimeout(ctx, g.callTimeout) + defer cancel() + + request := &kmsapi.EncryptRequest{ + Plaintext: plaintext, + Uid: uid, + } + response, err := g.kmsClient.Encrypt(ctx, request) + if err != nil { + return nil, err + } + return &kmsservice.EncryptResponse{ + Ciphertext: response.Ciphertext, + KeyID: response.KeyId, + Annotations: response.Annotations, + }, nil +} + +// Status returns the status of the KMSv2 provider. +func (g *gRPCService) Status(ctx context.Context) (*kmsservice.StatusResponse, error) { + ctx, cancel := context.WithTimeout(ctx, g.callTimeout) + defer cancel() + + request := &kmsapi.StatusRequest{} + response, err := g.kmsClient.Status(ctx, request) + if err != nil { + return nil, err + } + return &kmsservice.StatusResponse{Version: response.Version, Healthz: response.Healthz, KeyID: response.KeyId}, nil +} + +func recordMetricsInterceptor(providerName string) grpc.UnaryClientInterceptor { + return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + start := NowFunc() + respErr := invoker(ctx, method, req, reply, cc, opts...) + elapsed := NowFunc().Sub(start) + metrics.RecordKMSOperationLatency(providerName, method, elapsed, respErr) + return respErr + } +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/OWNERS b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/OWNERS new file mode 100644 index 0000000000..fa20d4cbeb --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/OWNERS @@ -0,0 +1,9 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: + - api-approvers +reviewers: + - sig-auth-api-reviewers diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/api.pb.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/api.pb.go new file mode 100644 index 0000000000..c7bdd66f0f --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/api.pb.go @@ -0,0 +1,131 @@ +/* +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 protoc-gen-gogo. DO NOT EDIT. +// source: api.proto + +package v2 + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// EncryptedObject is the representation of data stored in etcd after envelope encryption. +type EncryptedObject struct { + // EncryptedData is the encrypted data. + EncryptedData []byte `protobuf:"bytes,1,opt,name=encryptedData,proto3" json:"encryptedData,omitempty"` + // KeyID is the KMS key ID used for encryption operations. + KeyID string `protobuf:"bytes,2,opt,name=keyID,proto3" json:"keyID,omitempty"` + // EncryptedDEK is the encrypted DEK. + EncryptedDEK []byte `protobuf:"bytes,3,opt,name=encryptedDEK,proto3" json:"encryptedDEK,omitempty"` + // Annotations is additional metadata that was provided by the KMS plugin. + Annotations map[string][]byte `protobuf:"bytes,4,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EncryptedObject) Reset() { *m = EncryptedObject{} } +func (m *EncryptedObject) String() string { return proto.CompactTextString(m) } +func (*EncryptedObject) ProtoMessage() {} +func (*EncryptedObject) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{0} +} +func (m *EncryptedObject) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EncryptedObject.Unmarshal(m, b) +} +func (m *EncryptedObject) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EncryptedObject.Marshal(b, m, deterministic) +} +func (m *EncryptedObject) XXX_Merge(src proto.Message) { + xxx_messageInfo_EncryptedObject.Merge(m, src) +} +func (m *EncryptedObject) XXX_Size() int { + return xxx_messageInfo_EncryptedObject.Size(m) +} +func (m *EncryptedObject) XXX_DiscardUnknown() { + xxx_messageInfo_EncryptedObject.DiscardUnknown(m) +} + +var xxx_messageInfo_EncryptedObject proto.InternalMessageInfo + +func (m *EncryptedObject) GetEncryptedData() []byte { + if m != nil { + return m.EncryptedData + } + return nil +} + +func (m *EncryptedObject) GetKeyID() string { + if m != nil { + return m.KeyID + } + return "" +} + +func (m *EncryptedObject) GetEncryptedDEK() []byte { + if m != nil { + return m.EncryptedDEK + } + return nil +} + +func (m *EncryptedObject) GetAnnotations() map[string][]byte { + if m != nil { + return m.Annotations + } + return nil +} + +func init() { + proto.RegisterType((*EncryptedObject)(nil), "v2.EncryptedObject") + proto.RegisterMapType((map[string][]byte)(nil), "v2.EncryptedObject.AnnotationsEntry") +} + +func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } + +var fileDescriptor_00212fb1f9d3bf1c = []byte{ + // 244 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0xb1, 0x4b, 0x03, 0x31, + 0x14, 0xc6, 0xc9, 0x9d, 0x0a, 0x97, 0x9e, 0x58, 0x82, 0xc3, 0xe1, 0x74, 0x94, 0x0e, 0x37, 0x25, + 0x10, 0x97, 0x22, 0x52, 0x50, 0x7a, 0x82, 0x38, 0x08, 0x19, 0xdd, 0xd2, 0xfa, 0x28, 0x67, 0x6a, + 0x12, 0x92, 0x18, 0xc8, 0x9f, 0xee, 0x26, 0x4d, 0x95, 0xda, 0xdb, 0xde, 0xf7, 0xf1, 0xfb, 0xe0, + 0xc7, 0xc3, 0x95, 0xb4, 0x03, 0xb5, 0xce, 0x04, 0x43, 0x8a, 0xc8, 0x67, 0xdf, 0x08, 0x5f, 0xf5, + 0x7a, 0xe3, 0x92, 0x0d, 0xf0, 0xfe, 0xba, 0xfe, 0x80, 0x4d, 0x20, 0x73, 0x7c, 0x09, 0x7f, 0xd5, + 0x4a, 0x06, 0xd9, 0xa0, 0x16, 0x75, 0xb5, 0x38, 0x2d, 0xc9, 0x35, 0x3e, 0x57, 0x90, 0x9e, 0x57, + 0x4d, 0xd1, 0xa2, 0xae, 0x12, 0x87, 0x40, 0x66, 0xb8, 0x3e, 0x62, 0xfd, 0x4b, 0x53, 0xe6, 0xe9, + 0x49, 0x47, 0x9e, 0xf0, 0x44, 0x6a, 0x6d, 0x82, 0x0c, 0x83, 0xd1, 0xbe, 0x39, 0x6b, 0xcb, 0x6e, + 0xc2, 0xe7, 0x34, 0x72, 0x3a, 0x32, 0xa1, 0x0f, 0x47, 0xac, 0xd7, 0xc1, 0x25, 0xf1, 0x7f, 0x78, + 0xb3, 0xc4, 0xd3, 0x31, 0x40, 0xa6, 0xb8, 0x54, 0x90, 0xb2, 0x71, 0x25, 0xf6, 0xe7, 0xde, 0x33, + 0xca, 0xdd, 0x17, 0x64, 0xcf, 0x5a, 0x1c, 0xc2, 0x5d, 0xb1, 0x40, 0x8f, 0xcb, 0xb7, 0x7b, 0xb5, + 0xf0, 0x74, 0x30, 0x4c, 0xda, 0xc1, 0x83, 0x8b, 0xe0, 0x98, 0x55, 0x5b, 0xe6, 0x83, 0x71, 0x72, + 0x0b, 0x2c, 0x93, 0xec, 0x57, 0x9d, 0x81, 0x8e, 0xb0, 0x33, 0x16, 0x98, 0xfa, 0xf4, 0x91, 0xb3, + 0xc8, 0xd7, 0x17, 0xf9, 0x8d, 0xb7, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x00, 0x80, 0x43, 0x93, + 0x53, 0x01, 0x00, 0x00, +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/api.proto b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/api.proto new file mode 100644 index 0000000000..9ca2ccf96f --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/api.proto @@ -0,0 +1,36 @@ +/* +Copyright 2022 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. +*/ + +// To regenerate api.pb.go run `hack/update-codegen.sh protobindings` +syntax = "proto3"; + +package v2; +option go_package = "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2"; + +// EncryptedObject is the representation of data stored in etcd after envelope encryption. +message EncryptedObject { + // EncryptedData is the encrypted data. + bytes encryptedData = 1; + + // KeyID is the KMS key ID used for encryption operations. + string keyID = 2; + + // EncryptedDEK is the encrypted DEK. + bytes encryptedDEK = 3; + + // Annotations is additional metadata that was provided by the KMS plugin. + map annotations = 4; +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/v2.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/v2.go new file mode 100644 index 0000000000..878b19f229 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/v2.go @@ -0,0 +1,18 @@ +/* +Copyright 2022 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 v2 contains definition of kms-plugin's serialized types. +package v2 diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics/metrics.go new file mode 100644 index 0000000000..ff3903805d --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics/metrics.go @@ -0,0 +1,304 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "crypto/sha256" + "errors" + "fmt" + "hash" + "sync" + "time" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" + "k8s.io/klog/v2" + "k8s.io/utils/lru" +) + +const ( + namespace = "apiserver" + subsystem = "envelope_encryption" + FromStorageLabel = "from_storage" + ToStorageLabel = "to_storage" +) + +type metricLabels struct { + transformationType string + providerName string + keyIDHash string +} + +/* + * By default, all the following metrics are defined as falling under + * ALPHA stability level https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/1209-metrics-stability/kubernetes-control-plane-metrics-stability.md#stability-classes) + * + * Promoting the stability level of the metric is a responsibility of the component owner, since it + * involves explicitly acknowledging support for the metric across multiple releases, in accordance with + * the metric stability policy. + */ +var ( + lockLastFromStorage sync.Mutex + lockLastToStorage sync.Mutex + lockRecordKeyID sync.Mutex + lockRecordKeyIDStatus sync.Mutex + + lastFromStorage time.Time + lastToStorage time.Time + keyIDHashTotalMetricLabels *lru.Cache + keyIDHashStatusLastTimestampSecondsMetricLabels *lru.Cache + cacheSize = 100 + + // This metric is only used for KMS v1 API. + dekCacheFillPercent = metrics.NewGauge( + &metrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "dek_cache_fill_percent", + Help: "Percent of the cache slots currently occupied by cached DEKs.", + StabilityLevel: metrics.ALPHA, + }, + ) + + // This metric is only used for KMS v1 API. + dekCacheInterArrivals = metrics.NewHistogramVec( + &metrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "dek_cache_inter_arrival_time_seconds", + Help: "Time (in seconds) of inter arrival of transformation requests.", + StabilityLevel: metrics.ALPHA, + Buckets: metrics.ExponentialBuckets(60, 2, 10), + }, + []string{"transformation_type"}, + ) + + // These metrics are made public to be used by unit tests. + KMSOperationsLatencyMetric = metrics.NewHistogramVec( + &metrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "kms_operations_latency_seconds", + Help: "KMS operation duration with gRPC error code status total.", + StabilityLevel: metrics.ALPHA, + // Use custom buckets to avoid the default buckets which are too small for KMS operations. + // Start 0.1ms with the last bucket being [~52s, +Inf) + Buckets: metrics.ExponentialBuckets(0.0001, 2, 20), + }, + []string{"provider_name", "method_name", "grpc_status_code"}, + ) + + // keyIDHashTotal is the number of times a keyID is used + // e.g. apiserver_envelope_encryption_key_id_hash_total counter + // apiserver_envelope_encryption_key_id_hash_total{key_id_hash="sha256", + // provider_name="providerName",transformation_type="from_storage"} 1 + KeyIDHashTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "key_id_hash_total", + Help: "Number of times a keyID is used split by transformation type and provider.", + StabilityLevel: metrics.ALPHA, + }, + []string{"transformation_type", "provider_name", "key_id_hash"}, + ) + + // keyIDHashLastTimestampSeconds is the last time in seconds when a keyID was used + // e.g. apiserver_envelope_encryption_key_id_hash_last_timestamp_seconds{key_id_hash="sha256", provider_name="providerName",transformation_type="from_storage"} 1.674865558833728e+09 + KeyIDHashLastTimestampSeconds = metrics.NewGaugeVec( + &metrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "key_id_hash_last_timestamp_seconds", + Help: "The last time in seconds when a keyID was used.", + StabilityLevel: metrics.ALPHA, + }, + []string{"transformation_type", "provider_name", "key_id_hash"}, + ) + + // keyIDHashStatusLastTimestampSeconds is the last time in seconds when a keyID was returned by the Status RPC call. + // e.g. apiserver_envelope_encryption_key_id_hash_status_last_timestamp_seconds{key_id_hash="sha256", provider_name="providerName"} 1.674865558833728e+09 + KeyIDHashStatusLastTimestampSeconds = metrics.NewGaugeVec( + &metrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "key_id_hash_status_last_timestamp_seconds", + Help: "The last time in seconds when a keyID was returned by the Status RPC call.", + StabilityLevel: metrics.ALPHA, + }, + []string{"provider_name", "key_id_hash"}, + ) + + InvalidKeyIDFromStatusTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "invalid_key_id_from_status_total", + Help: "Number of times an invalid keyID is returned by the Status RPC call split by error.", + StabilityLevel: metrics.ALPHA, + }, + []string{"provider_name", "error"}, + ) +) + +var registerMetricsFunc sync.Once +var hashPool *sync.Pool + +func registerLRUMetrics() { + if keyIDHashTotalMetricLabels != nil { + keyIDHashTotalMetricLabels.Clear() + } + if keyIDHashStatusLastTimestampSecondsMetricLabels != nil { + keyIDHashStatusLastTimestampSecondsMetricLabels.Clear() + } + + keyIDHashTotalMetricLabels = lru.NewWithEvictionFunc(cacheSize, func(key lru.Key, _ interface{}) { + item := key.(metricLabels) + if deleted := KeyIDHashTotal.DeleteLabelValues(item.transformationType, item.providerName, item.keyIDHash); deleted { + klog.InfoS("Deleted keyIDHashTotalMetricLabels", "transformationType", item.transformationType, + "providerName", item.providerName, "keyIDHash", item.keyIDHash) + } + if deleted := KeyIDHashLastTimestampSeconds.DeleteLabelValues(item.transformationType, item.providerName, item.keyIDHash); deleted { + klog.InfoS("Deleted keyIDHashLastTimestampSecondsMetricLabels", "transformationType", item.transformationType, + "providerName", item.providerName, "keyIDHash", item.keyIDHash) + } + }) + keyIDHashStatusLastTimestampSecondsMetricLabels = lru.NewWithEvictionFunc(cacheSize, func(key lru.Key, _ interface{}) { + item := key.(metricLabels) + if deleted := KeyIDHashStatusLastTimestampSeconds.DeleteLabelValues(item.providerName, item.keyIDHash); deleted { + klog.InfoS("Deleted keyIDHashStatusLastTimestampSecondsMetricLabels", "providerName", item.providerName, "keyIDHash", item.keyIDHash) + } + }) +} +func RegisterMetrics() { + registerMetricsFunc.Do(func() { + registerLRUMetrics() + hashPool = &sync.Pool{ + New: func() interface{} { + return sha256.New() + }, + } + legacyregistry.MustRegister(dekCacheFillPercent) + legacyregistry.MustRegister(dekCacheInterArrivals) + legacyregistry.MustRegister(KeyIDHashTotal) + legacyregistry.MustRegister(KeyIDHashLastTimestampSeconds) + legacyregistry.MustRegister(KeyIDHashStatusLastTimestampSeconds) + legacyregistry.MustRegister(InvalidKeyIDFromStatusTotal) + legacyregistry.MustRegister(KMSOperationsLatencyMetric) + }) +} + +// RecordKeyID records total count and last time in seconds when a KeyID was used for TransformFromStorage and TransformToStorage operations +func RecordKeyID(transformationType, providerName, keyID string) { + lockRecordKeyID.Lock() + defer lockRecordKeyID.Unlock() + + keyIDHash := addLabelToCache(keyIDHashTotalMetricLabels, transformationType, providerName, keyID) + KeyIDHashTotal.WithLabelValues(transformationType, providerName, keyIDHash).Inc() + KeyIDHashLastTimestampSeconds.WithLabelValues(transformationType, providerName, keyIDHash).SetToCurrentTime() +} + +// RecordKeyIDFromStatus records last time in seconds when a KeyID was returned by the Status RPC call. +func RecordKeyIDFromStatus(providerName, keyID string) { + lockRecordKeyIDStatus.Lock() + defer lockRecordKeyIDStatus.Unlock() + + keyIDHash := addLabelToCache(keyIDHashStatusLastTimestampSecondsMetricLabels, "", providerName, keyID) + KeyIDHashStatusLastTimestampSeconds.WithLabelValues(providerName, keyIDHash).SetToCurrentTime() +} + +func RecordInvalidKeyIDFromStatus(providerName, errCode string) { + InvalidKeyIDFromStatusTotal.WithLabelValues(providerName, errCode).Inc() +} + +func RecordArrival(transformationType string, start time.Time) { + switch transformationType { + case FromStorageLabel: + lockLastFromStorage.Lock() + defer lockLastFromStorage.Unlock() + + if lastFromStorage.IsZero() { + lastFromStorage = start + } + dekCacheInterArrivals.WithLabelValues(transformationType).Observe(start.Sub(lastFromStorage).Seconds()) + lastFromStorage = start + case ToStorageLabel: + lockLastToStorage.Lock() + defer lockLastToStorage.Unlock() + + if lastToStorage.IsZero() { + lastToStorage = start + } + dekCacheInterArrivals.WithLabelValues(transformationType).Observe(start.Sub(lastToStorage).Seconds()) + lastToStorage = start + } +} + +func RecordDekCacheFillPercent(percent float64) { + dekCacheFillPercent.Set(percent) +} + +// RecordKMSOperationLatency records the latency of KMS operation. +func RecordKMSOperationLatency(providerName, methodName string, duration time.Duration, err error) { + KMSOperationsLatencyMetric.WithLabelValues(providerName, methodName, getErrorCode(err)).Observe(duration.Seconds()) +} + +type gRPCError interface { + GRPCStatus() *status.Status +} + +func getErrorCode(err error) string { + if err == nil { + return codes.OK.String() + } + + // handle errors wrapped with fmt.Errorf and similar + var s gRPCError + if errors.As(err, &s) { + return s.GRPCStatus().Code().String() + } + + // This is not gRPC error. The operation must have failed before gRPC + // method was called, otherwise we would get gRPC error. + return "unknown-non-grpc" +} + +func getHash(data string) string { + h := hashPool.Get().(hash.Hash) + h.Reset() + h.Write([]byte(data)) + result := fmt.Sprintf("sha256:%x", h.Sum(nil)) + hashPool.Put(h) + return result +} + +func addLabelToCache(c *lru.Cache, transformationType, providerName, keyID string) string { + keyIDHash := "" + // only get hash if the keyID is not empty + if len(keyID) > 0 { + keyIDHash = getHash(keyID) + } + c.Add(metricLabels{ + transformationType: transformationType, + providerName: providerName, + keyIDHash: keyIDHash, + }, nil) // value is irrelevant, this is a set and not a map + return keyIDHash +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/identity/identity.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/identity/identity.go new file mode 100644 index 0000000000..8d967d7068 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/identity/identity.go @@ -0,0 +1,57 @@ +/* +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 identity + +import ( + "bytes" + "context" + "fmt" + + "k8s.io/apiserver/pkg/storage/value" +) + +var ( + transformer = identityTransformer{} + encryptedPrefix = []byte("k8s:enc:") + errEncryptedData = fmt.Errorf("identity transformer tried to read encrypted data") +) + +// identityTransformer performs no transformation on provided data, but validates +// that the data is not encrypted data during TransformFromStorage +type identityTransformer struct{} + +// NewEncryptCheckTransformer returns an identityTransformer which returns an error +// on attempts to read encrypted data +func NewEncryptCheckTransformer() value.Transformer { + return transformer +} + +// TransformFromStorage returns the input bytes if the data is not encrypted +func (identityTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { + // identityTransformer has to return an error if the data is encoded using another transformer. + // JSON data starts with '{'. Protobuf data has a prefix 'k8s[\x00-\xFF]'. + // Prefix 'k8s:enc:' is reserved for encrypted data on disk. + if bytes.HasPrefix(data, encryptedPrefix) { + return nil, false, errEncryptedData + } + return data, false, nil +} + +// TransformToStorage implements the Transformer interface for identityTransformer +func (identityTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) { + return data, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/secretbox/secretbox.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/secretbox/secretbox.go new file mode 100644 index 0000000000..9aec8acd39 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/secretbox/secretbox.go @@ -0,0 +1,70 @@ +/* +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 secretbox transforms values for storage at rest using XSalsa20 and Poly1305. +package secretbox + +import ( + "context" + "crypto/rand" + "fmt" + + "golang.org/x/crypto/nacl/secretbox" + + "k8s.io/apiserver/pkg/storage/value" +) + +// secretbox implements at rest encryption of the provided values given a 32 byte secret key. +// Uses a standard 24 byte nonce (placed at the beginning of the cipher text) generated +// from crypto/rand. Does not perform authentication of the data at rest. +type secretboxTransformer struct { + key [32]byte +} + +const nonceSize = 24 + +// NewSecretboxTransformer takes the given key and performs encryption and decryption on the given +// data. +func NewSecretboxTransformer(key [32]byte) value.Transformer { + return &secretboxTransformer{key: key} +} + +func (t *secretboxTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { + if len(data) < (secretbox.Overhead + nonceSize) { + return nil, false, fmt.Errorf("the stored data was shorter than the required size") + } + var nonce [nonceSize]byte + copy(nonce[:], data[:nonceSize]) + data = data[nonceSize:] + out := make([]byte, 0, len(data)-secretbox.Overhead) + result, ok := secretbox.Open(out, data, &nonce, &t.key) + if !ok { + return nil, false, fmt.Errorf("output array was not large enough for encryption") + } + return result, false, nil +} + +func (t *secretboxTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) { + var nonce [nonceSize]byte + n, err := rand.Read(nonce[:]) + if err != nil { + return nil, err + } + if n != nonceSize { + return nil, fmt.Errorf("unable to read sufficient random bytes") + } + return secretbox.Seal(nonce[:], data, &nonce, &t.key), nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/metrics.go b/vendor/k8s.io/apiserver/pkg/storage/value/metrics.go new file mode 100644 index 0000000000..c8fd2f4c04 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/metrics.go @@ -0,0 +1,140 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package value + +import ( + "sync" + "time" + + "google.golang.org/grpc/status" + + "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +const ( + namespace = "apiserver" + subsystem = "storage" +) + +/* + * By default, all the following metrics are defined as falling under + * ALPHA stability level https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/1209-metrics-stability/kubernetes-control-plane-metrics-stability.md#stability-classes) + * + * Promoting the stability level of the metric is a responsibility of the component owner, since it + * involves explicitly acknowledging support for the metric across multiple releases, in accordance with + * the metric stability policy. + */ +var ( + transformerLatencies = metrics.NewHistogramVec( + &metrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "transformation_duration_seconds", + Help: "Latencies in seconds of value transformation operations.", + // In-process transformations (ex. AES CBC) complete on the order of 20 microseconds. However, when + // external KMS is involved latencies may climb into hundreds of milliseconds. + Buckets: metrics.ExponentialBuckets(5e-6, 2, 25), + StabilityLevel: metrics.ALPHA, + }, + []string{"transformation_type", "transformer_prefix"}, + ) + + transformerOperationsTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "transformation_operations_total", + Help: "Total number of transformations.", + StabilityLevel: metrics.ALPHA, + }, + []string{"transformation_type", "transformer_prefix", "status"}, + ) + + envelopeTransformationCacheMissTotal = metrics.NewCounter( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "envelope_transformation_cache_misses_total", + Help: "Total number of cache misses while accessing key decryption key(KEK).", + StabilityLevel: metrics.ALPHA, + }, + ) + + dataKeyGenerationLatencies = metrics.NewHistogram( + &metrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "data_key_generation_duration_seconds", + Help: "Latencies in seconds of data encryption key(DEK) generation operations.", + Buckets: metrics.ExponentialBuckets(5e-6, 2, 14), + StabilityLevel: metrics.ALPHA, + }, + ) + + dataKeyGenerationFailuresTotal = metrics.NewCounter( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "data_key_generation_failures_total", + Help: "Total number of failed data encryption key(DEK) generation operations.", + StabilityLevel: metrics.ALPHA, + }, + ) +) + +var registerMetrics sync.Once + +func RegisterMetrics() { + registerMetrics.Do(func() { + legacyregistry.MustRegister(transformerLatencies) + legacyregistry.MustRegister(transformerOperationsTotal) + legacyregistry.MustRegister(envelopeTransformationCacheMissTotal) + legacyregistry.MustRegister(dataKeyGenerationLatencies) + legacyregistry.MustRegister(dataKeyGenerationFailuresTotal) + }) +} + +// RecordTransformation records latencies and count of TransformFromStorage and TransformToStorage operations. +// Note that transformation_failures_total metric is deprecated, use transformation_operations_total instead. +func RecordTransformation(transformationType, transformerPrefix string, elapsed time.Duration, err error) { + transformerOperationsTotal.WithLabelValues(transformationType, transformerPrefix, status.Code(err).String()).Inc() + + if err == nil { + transformerLatencies.WithLabelValues(transformationType, transformerPrefix).Observe(elapsed.Seconds()) + } +} + +// RecordCacheMiss records a miss on Key Encryption Key(KEK) - call to KMS was required to decrypt KEK. +func RecordCacheMiss() { + envelopeTransformationCacheMissTotal.Inc() +} + +// RecordDataKeyGeneration records latencies and count of Data Encryption Key generation operations. +func RecordDataKeyGeneration(start time.Time, err error) { + if err != nil { + dataKeyGenerationFailuresTotal.Inc() + return + } + + dataKeyGenerationLatencies.Observe(sinceInSeconds(start)) +} + +// sinceInSeconds gets the time since the specified start in seconds. +func sinceInSeconds(start time.Time) float64 { + return time.Since(start).Seconds() +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/transformer.go b/vendor/k8s.io/apiserver/pkg/storage/value/transformer.go new file mode 100644 index 0000000000..a6a4aa184d --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/transformer.go @@ -0,0 +1,166 @@ +/* +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 value contains methods for assisting with transformation of values in storage. +package value + +import ( + "bytes" + "context" + "fmt" + "time" + + "k8s.io/apimachinery/pkg/util/errors" +) + +func init() { + RegisterMetrics() +} + +// Context is additional information that a storage transformation may need to verify the data at rest. +type Context interface { + // AuthenticatedData should return an array of bytes that describes the current value. If the value changes, + // the transformer may report the value as unreadable or tampered. This may be nil if no such description exists + // or is needed. For additional verification, set this to data that strongly identifies the value, such as + // the key and creation version of the stored data. + AuthenticatedData() []byte +} + +// Transformer allows a value to be transformed before being read from or written to the underlying store. The methods +// must be able to undo the transformation caused by the other. +type Transformer interface { + // TransformFromStorage may transform the provided data from its underlying storage representation or return an error. + // Stale is true if the object on disk is stale and a write to etcd should be issued, even if the contents of the object + // have not changed. + TransformFromStorage(ctx context.Context, data []byte, dataCtx Context) (out []byte, stale bool, err error) + // TransformToStorage may transform the provided data into the appropriate form in storage or return an error. + TransformToStorage(ctx context.Context, data []byte, dataCtx Context) (out []byte, err error) +} + +// DefaultContext is a simple implementation of Context for a slice of bytes. +type DefaultContext []byte + +// AuthenticatedData returns itself. +func (c DefaultContext) AuthenticatedData() []byte { return c } + +// PrefixTransformer holds a transformer interface and the prefix that the transformation is located under. +type PrefixTransformer struct { + Prefix []byte + Transformer Transformer +} + +type prefixTransformers struct { + transformers []PrefixTransformer + err error +} + +var _ Transformer = &prefixTransformers{} + +// NewPrefixTransformers supports the Transformer interface by checking the incoming data against the provided +// prefixes in order. The first matching prefix will be used to transform the value (the prefix is stripped +// before the Transformer interface is invoked). The first provided transformer will be used when writing to +// the store. +func NewPrefixTransformers(err error, transformers ...PrefixTransformer) Transformer { + if err == nil { + err = fmt.Errorf("the provided value does not match any of the supported transformers") + } + return &prefixTransformers{ + transformers: transformers, + err: err, + } +} + +// TransformFromStorage finds the first transformer with a prefix matching the provided data and returns +// the result of transforming the value. It will always mark any transformation as stale that is not using +// the first transformer. +func (t *prefixTransformers) TransformFromStorage(ctx context.Context, data []byte, dataCtx Context) ([]byte, bool, error) { + start := time.Now() + var errs []error + for i, transformer := range t.transformers { + if bytes.HasPrefix(data, transformer.Prefix) { + result, stale, err := transformer.Transformer.TransformFromStorage(ctx, data[len(transformer.Prefix):], dataCtx) + // To migrate away from encryption, user can specify an identity transformer higher up + // (in the config file) than the encryption transformer. In that scenario, the identity transformer needs to + // identify (during reads from disk) whether the data being read is encrypted or not. If the data is encrypted, + // it shall throw an error, but that error should not prevent the next subsequent transformer from being tried. + if len(transformer.Prefix) == 0 && err != nil { + continue + } + if len(transformer.Prefix) == 0 { + RecordTransformation("from_storage", "identity", time.Since(start), err) + } else { + RecordTransformation("from_storage", string(transformer.Prefix), time.Since(start), err) + } + + // It is valid to have overlapping prefixes when the same encryption provider + // is specified multiple times but with different keys (the first provider is + // being rotated to and some later provider is being rotated away from). + // + // Example: + // + // { + // "aescbc": { + // "keys": [ + // { + // "name": "2", + // "secret": "some key 2" + // } + // ] + // } + // }, + // { + // "aescbc": { + // "keys": [ + // { + // "name": "1", + // "secret": "some key 1" + // } + // ] + // } + // }, + // + // The transformers for both aescbc configs share the prefix k8s:enc:aescbc:v1: + // but a failure in the first one should not prevent a later match from being attempted. + // Thus we never short-circuit on a prefix match that results in an error. + if err != nil { + errs = append(errs, err) + continue + } + + return result, stale || i != 0, err + } + } + if err := errors.Reduce(errors.NewAggregate(errs)); err != nil { + return nil, false, err + } + RecordTransformation("from_storage", "unknown", time.Since(start), t.err) + return nil, false, t.err +} + +// TransformToStorage uses the first transformer and adds its prefix to the data. +func (t *prefixTransformers) TransformToStorage(ctx context.Context, data []byte, dataCtx Context) ([]byte, error) { + start := time.Now() + transformer := t.transformers[0] + result, err := transformer.Transformer.TransformToStorage(ctx, data, dataCtx) + RecordTransformation("to_storage", string(transformer.Prefix), time.Since(start), err) + if err != nil { + return nil, err + } + prefixedData := make([]byte, len(transformer.Prefix), len(result)+len(transformer.Prefix)) + copy(prefixedData, transformer.Prefix) + prefixedData = append(prefixedData, result...) + return prefixedData, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storageversion/OWNERS b/vendor/k8s.io/apiserver/pkg/storageversion/OWNERS new file mode 100644 index 0000000000..869b3da0dc --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storageversion/OWNERS @@ -0,0 +1,5 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - caesarxuchao + - roycaihw diff --git a/vendor/k8s.io/apiserver/pkg/storageversion/manager.go b/vendor/k8s.io/apiserver/pkg/storageversion/manager.go new file mode 100644 index 0000000000..0e0d9542b0 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storageversion/manager.go @@ -0,0 +1,294 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package storageversion + +import ( + "fmt" + "sort" + "sync" + "sync/atomic" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + _ "k8s.io/component-base/metrics/prometheus/workqueue" // for workqueue metric registration + "k8s.io/klog/v2" +) + +// ResourceInfo contains the information to register the resource to the +// storage version API. +type ResourceInfo struct { + GroupResource schema.GroupResource + + EncodingVersion string + // Used to calculate decodable versions. Can only be used after all + // equivalent versions are registered by InstallREST. + EquivalentResourceMapper runtime.EquivalentResourceRegistry + + // DirectlyDecodableVersions is a list of versions that the converter for REST storage knows how to convert. This + // contains items like apiextensions.k8s.io/v1beta1 even if we don't serve that version. + DirectlyDecodableVersions []schema.GroupVersion +} + +// Manager records the resources whose StorageVersions need updates, and provides a method to update those StorageVersions. +type Manager interface { + // AddResourceInfo records resources whose StorageVersions need updates + AddResourceInfo(resources ...*ResourceInfo) + // UpdateStorageVersions tries to update the StorageVersions of the recorded resources + UpdateStorageVersions(kubeAPIServerClientConfig *rest.Config, apiserverID string) + // PendingUpdate returns true if the StorageVersion of the given resource is still pending update. + PendingUpdate(gr schema.GroupResource) bool + // LastUpdateError returns the last error hit when updating the storage version of the given resource. + LastUpdateError(gr schema.GroupResource) error + // Completed returns true if updating StorageVersions of all recorded resources has completed. + Completed() bool +} + +var _ Manager = &defaultManager{} + +// defaultManager indicates if an apiserver has completed reporting its storage versions. +type defaultManager struct { + completed atomic.Bool + + mu sync.RWMutex + // managedResourceInfos records the ResourceInfos whose StorageVersions will get updated in the next + // UpdateStorageVersions call + managedResourceInfos map[*ResourceInfo]struct{} + // managedStatus records the update status of StorageVersion for each GroupResource. Since one + // ResourceInfo may expand into multiple GroupResource (e.g. ingresses.networking.k8s.io and ingresses.extensions), + // this map allows quick status lookup for a GroupResource, during API request handling. + managedStatus map[schema.GroupResource]*updateStatus +} + +type updateStatus struct { + done bool + lastErr error +} + +// NewDefaultManager creates a new defaultManager. +func NewDefaultManager() Manager { + s := &defaultManager{} + s.completed.Store(false) + s.managedResourceInfos = make(map[*ResourceInfo]struct{}) + s.managedStatus = make(map[schema.GroupResource]*updateStatus) + return s +} + +// AddResourceInfo adds ResourceInfo to the manager. +func (s *defaultManager) AddResourceInfo(resources ...*ResourceInfo) { + s.mu.Lock() + defer s.mu.Unlock() + for _, r := range resources { + s.managedResourceInfos[r] = struct{}{} + s.addPendingManagedStatusLocked(r) + } +} + +func (s *defaultManager) addPendingManagedStatusLocked(r *ResourceInfo) { + gvrs := r.EquivalentResourceMapper.EquivalentResourcesFor(r.GroupResource.WithVersion(""), "") + for _, gvr := range gvrs { + gr := gvr.GroupResource() + if _, ok := s.managedStatus[gr]; !ok { + s.managedStatus[gr] = &updateStatus{} + } + } +} + +// UpdateStorageVersions tries to update the StorageVersions of the recorded resources +func (s *defaultManager) UpdateStorageVersions(kubeAPIServerClientConfig *rest.Config, serverID string) { + clientset, err := kubernetes.NewForConfig(kubeAPIServerClientConfig) + if err != nil { + utilruntime.HandleError(fmt.Errorf("failed to get clientset: %v", err)) + return + } + sc := clientset.InternalV1alpha1().StorageVersions() + + s.mu.RLock() + resources := []ResourceInfo{} + for resource := range s.managedResourceInfos { + resources = append(resources, *resource) + } + s.mu.RUnlock() + hasFailure := false + // Sorting the list to make sure we have a consistent dedup result, and + // therefore avoid creating unnecessarily duplicated StorageVersion objects. + // For example, extensions.ingresses and networking.k8s.io.ingresses share + // the same underlying storage. Without sorting, in an HA cluster, one + // apiserver may dedup and update StorageVersion for extensions.ingresses, + // while another apiserver may dedup and update StorageVersion for + // networking.k8s.io.ingresses. The storage migrator (which migrates objects + // per GroupResource) will migrate these resources twice, since both + // StorageVersion objects have CommonEncodingVersion (each with one server registered). + sortResourceInfosByGroupResource(resources) + for _, r := range dedupResourceInfos(resources) { + decodableVersions := decodableVersions(r.DirectlyDecodableVersions, r.EquivalentResourceMapper, r.GroupResource) + gr := r.GroupResource + // Group must be a valid subdomain in DNS (RFC 1123) + if len(gr.Group) == 0 { + gr.Group = "core" + } + if err := updateStorageVersionFor(sc, serverID, gr, r.EncodingVersion, decodableVersions); err != nil { + utilruntime.HandleError(fmt.Errorf("failed to update storage version for %v: %v", r.GroupResource, err)) + s.recordStatusFailure(&r, err) + hasFailure = true + continue + } + klog.V(2).Infof("successfully updated storage version for %v", r.GroupResource) + s.recordStatusSuccess(&r) + } + if hasFailure { + return + } + klog.V(2).Infof("storage version updates complete") + s.setComplete() +} + +// dedupResourceInfos dedups ResourceInfos with the same underlying storage. +// ResourceInfos from the same Group with different Versions share the same underlying storage. +// ResourceInfos from different Groups may share the same underlying storage, e.g. +// networking.k8s.io ingresses and extensions ingresses. The StorageVersion manager +// only needs to update one StorageVersion for the equivalent Groups. +func dedupResourceInfos(infos []ResourceInfo) []ResourceInfo { + var ret []ResourceInfo + seen := make(map[schema.GroupResource]struct{}) + for _, info := range infos { + gr := info.GroupResource + if _, ok := seen[gr]; ok { + continue + } + gvrs := info.EquivalentResourceMapper.EquivalentResourcesFor(gr.WithVersion(""), "") + for _, gvr := range gvrs { + seen[gvr.GroupResource()] = struct{}{} + } + ret = append(ret, info) + } + return ret +} + +func sortResourceInfosByGroupResource(infos []ResourceInfo) { + sort.Sort(byGroupResource(infos)) +} + +type byGroupResource []ResourceInfo + +func (s byGroupResource) Len() int { return len(s) } + +func (s byGroupResource) Less(i, j int) bool { + if s[i].GroupResource.Group == s[j].GroupResource.Group { + return s[i].GroupResource.Resource < s[j].GroupResource.Resource + } + return s[i].GroupResource.Group < s[j].GroupResource.Group +} + +func (s byGroupResource) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// recordStatusSuccess marks updated ResourceInfo as completed. +func (s *defaultManager) recordStatusSuccess(r *ResourceInfo) { + s.mu.Lock() + defer s.mu.Unlock() + s.recordStatusSuccessLocked(r) +} + +func (s *defaultManager) recordStatusSuccessLocked(r *ResourceInfo) { + gvrs := r.EquivalentResourceMapper.EquivalentResourcesFor(r.GroupResource.WithVersion(""), "") + for _, gvr := range gvrs { + s.recordSuccessGroupResourceLocked(gvr.GroupResource()) + } +} + +func (s *defaultManager) recordSuccessGroupResourceLocked(gr schema.GroupResource) { + if _, ok := s.managedStatus[gr]; !ok { + return + } + s.managedStatus[gr].done = true + s.managedStatus[gr].lastErr = nil +} + +// recordStatusFailure records latest error updating ResourceInfo. +func (s *defaultManager) recordStatusFailure(r *ResourceInfo, err error) { + s.mu.Lock() + defer s.mu.Unlock() + s.recordStatusFailureLocked(r, err) +} + +func (s *defaultManager) recordStatusFailureLocked(r *ResourceInfo, err error) { + gvrs := r.EquivalentResourceMapper.EquivalentResourcesFor(r.GroupResource.WithVersion(""), "") + for _, gvr := range gvrs { + s.recordErrorGroupResourceLocked(gvr.GroupResource(), err) + } +} + +func (s *defaultManager) recordErrorGroupResourceLocked(gr schema.GroupResource, err error) { + if _, ok := s.managedStatus[gr]; !ok { + return + } + s.managedStatus[gr].lastErr = err +} + +// PendingUpdate returns if the StorageVersion of a resource is still wait to be updated. +func (s *defaultManager) PendingUpdate(gr schema.GroupResource) bool { + s.mu.RLock() + defer s.mu.RUnlock() + if _, ok := s.managedStatus[gr]; !ok { + return false + } + return !s.managedStatus[gr].done +} + +// LastUpdateError returns the last error hit when updating the storage version of the given resource. +func (s *defaultManager) LastUpdateError(gr schema.GroupResource) error { + s.mu.RLock() + defer s.mu.RUnlock() + if _, ok := s.managedStatus[gr]; !ok { + return fmt.Errorf("couldn't find managed status for %v", gr) + } + return s.managedStatus[gr].lastErr +} + +// setComplete marks the completion of updating StorageVersions. No write requests need to be blocked anymore. +func (s *defaultManager) setComplete() { + s.completed.Store(true) +} + +// Completed returns if updating StorageVersions has completed. +func (s *defaultManager) Completed() bool { + return s.completed.Load() +} + +func decodableVersions(directlyDecodableVersions []schema.GroupVersion, e runtime.EquivalentResourceRegistry, gr schema.GroupResource) []string { + var versions []string + for _, decodableVersions := range directlyDecodableVersions { + versions = append(versions, decodableVersions.String()) + } + + decodingGVRs := e.EquivalentResourcesFor(gr.WithVersion(""), "") + for _, v := range decodingGVRs { + found := false + for _, existingVersion := range versions { + if existingVersion == v.GroupVersion().String() { + found = true + } + } + if found { + continue + } + versions = append(versions, v.GroupVersion().String()) + } + return versions +} diff --git a/vendor/k8s.io/apiserver/pkg/storageversion/updater.go b/vendor/k8s.io/apiserver/pkg/storageversion/updater.go new file mode 100644 index 0000000000..ce4d87e91c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storageversion/updater.go @@ -0,0 +1,196 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package storageversion + +import ( + "context" + "fmt" + "time" + + "k8s.io/api/apiserverinternal/v1alpha1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/klog/v2" +) + +// Client has the methods required to update the storage version. +type Client interface { + Create(context.Context, *v1alpha1.StorageVersion, metav1.CreateOptions) (*v1alpha1.StorageVersion, error) + UpdateStatus(context.Context, *v1alpha1.StorageVersion, metav1.UpdateOptions) (*v1alpha1.StorageVersion, error) + Get(context.Context, string, metav1.GetOptions) (*v1alpha1.StorageVersion, error) +} + +// SetCommonEncodingVersion updates the CommonEncodingVersion and the AllEncodingVersionsEqual +// condition based on the StorageVersions. +func SetCommonEncodingVersion(sv *v1alpha1.StorageVersion) { + var oldCommonEncodingVersion *string + if sv.Status.CommonEncodingVersion != nil { + version := *sv.Status.CommonEncodingVersion + oldCommonEncodingVersion = &version + } + sv.Status.CommonEncodingVersion = nil + if len(sv.Status.StorageVersions) != 0 { + firstVersion := sv.Status.StorageVersions[0].EncodingVersion + agreed := true + for _, ssv := range sv.Status.StorageVersions { + if ssv.EncodingVersion != firstVersion { + agreed = false + break + } + } + if agreed { + sv.Status.CommonEncodingVersion = &firstVersion + } + } + + condition := v1alpha1.StorageVersionCondition{ + Type: v1alpha1.AllEncodingVersionsEqual, + Status: v1alpha1.ConditionFalse, + ObservedGeneration: sv.Generation, + LastTransitionTime: metav1.NewTime(time.Now()), + Reason: "CommonEncodingVersionUnset", + Message: "Common encoding version unset", + } + if sv.Status.CommonEncodingVersion != nil { + condition.Status = v1alpha1.ConditionTrue + condition.Reason = "CommonEncodingVersionSet" + condition.Message = "Common encoding version set" + } + forceTransition := false + if oldCommonEncodingVersion != nil && sv.Status.CommonEncodingVersion != nil && + *oldCommonEncodingVersion != *sv.Status.CommonEncodingVersion { + forceTransition = true + } + setStatusCondition(&sv.Status.Conditions, condition, forceTransition) +} + +func findStatusCondition(conditions []v1alpha1.StorageVersionCondition, + conditionType v1alpha1.StorageVersionConditionType) *v1alpha1.StorageVersionCondition { + for i := range conditions { + if conditions[i].Type == conditionType { + return &conditions[i] + } + } + return nil +} + +// setStatusCondition sets the corresponding condition in conditions to newCondition. +// conditions must be non-nil. +// 1. if the condition of the specified type already exists: all fields of the existing condition are updated to +// newCondition, LastTransitionTime is set to now if the new status differs from the old status +// 2. if a condition of the specified type does not exist: LastTransitionTime is set to now() if unset, +// and newCondition is appended +// +// NOTE: forceTransition allows overwriting LastTransitionTime even when the status doesn't change. +func setStatusCondition(conditions *[]v1alpha1.StorageVersionCondition, newCondition v1alpha1.StorageVersionCondition, + forceTransition bool) { + if conditions == nil { + return + } + + if newCondition.LastTransitionTime.IsZero() { + newCondition.LastTransitionTime = metav1.NewTime(time.Now()) + } + existingCondition := findStatusCondition(*conditions, newCondition.Type) + if existingCondition == nil { + *conditions = append(*conditions, newCondition) + return + } + + statusChanged := existingCondition.Status != newCondition.Status + if statusChanged || forceTransition { + existingCondition.LastTransitionTime = newCondition.LastTransitionTime + } + existingCondition.Status = newCondition.Status + existingCondition.Reason = newCondition.Reason + existingCondition.Message = newCondition.Message + existingCondition.ObservedGeneration = newCondition.ObservedGeneration +} + +// updateStorageVersionFor updates the storage version object for the resource. +func updateStorageVersionFor(c Client, apiserverID string, gr schema.GroupResource, encodingVersion string, decodableVersions []string) error { + retries := 3 + var retry int + var err error + for retry < retries { + err = singleUpdate(c, apiserverID, gr, encodingVersion, decodableVersions) + if err == nil { + return nil + } + if apierrors.IsAlreadyExists(err) || apierrors.IsConflict(err) { + time.Sleep(1 * time.Second) + continue + } + if err != nil { + klog.Errorf("retry %d, failed to update storage version for %v: %v", retry, gr, err) + retry++ + time.Sleep(1 * time.Second) + } + } + return err +} + +func singleUpdate(c Client, apiserverID string, gr schema.GroupResource, encodingVersion string, decodableVersions []string) error { + shouldCreate := false + name := fmt.Sprintf("%s.%s", gr.Group, gr.Resource) + sv, err := c.Get(context.TODO(), name, metav1.GetOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return err + } + if apierrors.IsNotFound(err) { + shouldCreate = true + sv = &v1alpha1.StorageVersion{} + sv.ObjectMeta.Name = name + } + updatedSV := localUpdateStorageVersion(sv, apiserverID, encodingVersion, decodableVersions) + if shouldCreate { + createdSV, err := c.Create(context.TODO(), updatedSV, metav1.CreateOptions{}) + if err != nil { + return err + } + // assign the calculated status to the object just created, then update status + createdSV.Status = updatedSV.Status + _, err = c.UpdateStatus(context.TODO(), createdSV, metav1.UpdateOptions{}) + return err + } + _, err = c.UpdateStatus(context.TODO(), updatedSV, metav1.UpdateOptions{}) + return err +} + +// localUpdateStorageVersion updates the input storageversion with given server storageversion info. +// The function updates the input storageversion in place. +func localUpdateStorageVersion(sv *v1alpha1.StorageVersion, apiserverID, encodingVersion string, decodableVersions []string) *v1alpha1.StorageVersion { + newSSV := v1alpha1.ServerStorageVersion{ + APIServerID: apiserverID, + EncodingVersion: encodingVersion, + DecodableVersions: decodableVersions, + } + foundSSV := false + for i, ssv := range sv.Status.StorageVersions { + if ssv.APIServerID == apiserverID { + sv.Status.StorageVersions[i] = newSSV + foundSSV = true + break + } + } + if !foundSSV { + sv.Status.StorageVersions = append(sv.Status.StorageVersions, newSSV) + } + SetCommonEncodingVersion(sv) + return sv +} diff --git a/vendor/k8s.io/apiserver/pkg/util/apihelpers/helpers.go b/vendor/k8s.io/apiserver/pkg/util/apihelpers/helpers.go new file mode 100644 index 0000000000..ffc1a0e406 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/apihelpers/helpers.go @@ -0,0 +1,100 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package apihelpers + +import ( + "sort" + + flowcontrol "k8s.io/api/flowcontrol/v1beta3" +) + +// SetFlowSchemaCondition sets conditions. +func SetFlowSchemaCondition(flowSchema *flowcontrol.FlowSchema, newCondition flowcontrol.FlowSchemaCondition) { + existingCondition := GetFlowSchemaConditionByType(flowSchema, newCondition.Type) + if existingCondition == nil { + flowSchema.Status.Conditions = append(flowSchema.Status.Conditions, newCondition) + return + } + + if existingCondition.Status != newCondition.Status { + existingCondition.Status = newCondition.Status + existingCondition.LastTransitionTime = newCondition.LastTransitionTime + } + + existingCondition.Reason = newCondition.Reason + existingCondition.Message = newCondition.Message +} + +// GetFlowSchemaConditionByType gets conditions. +func GetFlowSchemaConditionByType(flowSchema *flowcontrol.FlowSchema, conditionType flowcontrol.FlowSchemaConditionType) *flowcontrol.FlowSchemaCondition { + for i := range flowSchema.Status.Conditions { + if flowSchema.Status.Conditions[i].Type == conditionType { + return &flowSchema.Status.Conditions[i] + } + } + return nil +} + +// SetPriorityLevelConfigurationCondition sets conditions. +func SetPriorityLevelConfigurationCondition(priorityLevel *flowcontrol.PriorityLevelConfiguration, newCondition flowcontrol.PriorityLevelConfigurationCondition) { + existingCondition := GetPriorityLevelConfigurationConditionByType(priorityLevel, newCondition.Type) + if existingCondition == nil { + priorityLevel.Status.Conditions = append(priorityLevel.Status.Conditions, newCondition) + return + } + + if existingCondition.Status != newCondition.Status { + existingCondition.Status = newCondition.Status + existingCondition.LastTransitionTime = newCondition.LastTransitionTime + } + + existingCondition.Reason = newCondition.Reason + existingCondition.Message = newCondition.Message +} + +// GetPriorityLevelConfigurationConditionByType gets conditions. +func GetPriorityLevelConfigurationConditionByType(priorityLevel *flowcontrol.PriorityLevelConfiguration, conditionType flowcontrol.PriorityLevelConfigurationConditionType) *flowcontrol.PriorityLevelConfigurationCondition { + for i := range priorityLevel.Status.Conditions { + if priorityLevel.Status.Conditions[i].Type == conditionType { + return &priorityLevel.Status.Conditions[i] + } + } + return nil +} + +var _ sort.Interface = FlowSchemaSequence{} + +// FlowSchemaSequence holds sorted set of pointers to FlowSchema objects. +// FlowSchemaSequence implements `sort.Interface` +type FlowSchemaSequence []*flowcontrol.FlowSchema + +func (s FlowSchemaSequence) Len() int { + return len(s) +} + +func (s FlowSchemaSequence) Less(i, j int) bool { + // the flow-schema w/ lower matching-precedence is prior + if ip, jp := s[i].Spec.MatchingPrecedence, s[j].Spec.MatchingPrecedence; ip != jp { + return ip < jp + } + // sort alphabetically + return s[i].Name < s[j].Name +} + +func (s FlowSchemaSequence) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} diff --git a/vendor/k8s.io/apiserver/pkg/util/dryrun/dryrun.go b/vendor/k8s.io/apiserver/pkg/util/dryrun/dryrun.go new file mode 100644 index 0000000000..3e28c29345 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/dryrun/dryrun.go @@ -0,0 +1,22 @@ +/* +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 dryrun + +// IsDryRun returns true if the DryRun flag is an actual dry-run. +func IsDryRun(flag []string) bool { + return len(flag) > 0 +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/OWNERS b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/OWNERS new file mode 100644 index 0000000000..2556c589fd --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/OWNERS @@ -0,0 +1,15 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - lavalamp + - deads2k + - yue9944882 + - MikeSpreitzer +reviewers: + - lavalamp + - deads2k + - yue9944882 + - MikeSpreitzer +labels: + - sig/api-machinery + - area/apiserver diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_context.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_context.go new file mode 100644 index 0000000000..1cd59049de --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_context.go @@ -0,0 +1,93 @@ +/* +Copyright 2021 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 flowcontrol + +import ( + "context" + "sync" +) + +type priorityAndFairnessKeyType int + +const ( + // priorityAndFairnessInitializationSignalKey is a key under which + // initialization signal function for watch requests is stored + // in the context. + priorityAndFairnessInitializationSignalKey priorityAndFairnessKeyType = iota +) + +// WithInitializationSignal creates a copy of parent context with +// priority and fairness initialization signal value. +func WithInitializationSignal(ctx context.Context, signal InitializationSignal) context.Context { + return context.WithValue(ctx, priorityAndFairnessInitializationSignalKey, signal) +} + +// initializationSignalFrom returns an initialization signal function +// which when called signals that watch initialization has already finished +// to priority and fairness dispatcher. +func initializationSignalFrom(ctx context.Context) (InitializationSignal, bool) { + signal, ok := ctx.Value(priorityAndFairnessInitializationSignalKey).(InitializationSignal) + return signal, ok && signal != nil +} + +// WatchInitialized sends a signal to priority and fairness dispatcher +// that a given watch request has already been initialized. +func WatchInitialized(ctx context.Context) { + if signal, ok := initializationSignalFrom(ctx); ok { + signal.Signal() + } +} + +// RequestDelegated informs the priority and fairness dispatcher that +// a given request has been delegated to an aggregated API +// server. No-op when priority and fairness is disabled. +func RequestDelegated(ctx context.Context) { + // The watch initialization signal doesn't traverse request + // boundaries, so we generously fire it as soon as we know + // that the request won't be serviced locally. Safe to call + // for non-watch requests. + WatchInitialized(ctx) +} + +// InitializationSignal is an interface that allows sending and handling +// initialization signals. +type InitializationSignal interface { + // Signal notifies the dispatcher about finished initialization. + Signal() + // Wait waits for the initialization signal. + Wait() +} + +type initializationSignal struct { + once sync.Once + done chan struct{} +} + +func NewInitializationSignal() InitializationSignal { + return &initializationSignal{ + once: sync.Once{}, + done: make(chan struct{}), + } +} + +func (i *initializationSignal) Signal() { + i.once.Do(func() { close(i.done) }) +} + +func (i *initializationSignal) Wait() { + <-i.done +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller.go new file mode 100644 index 0000000000..2048a6ef6b --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller.go @@ -0,0 +1,1109 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package flowcontrol + +import ( + "context" + "crypto/sha256" + "encoding/binary" + "errors" + "fmt" + "math" + "math/rand" + "sort" + "sync" + "time" + + "github.com/google/go-cmp/cmp" + apiequality "k8s.io/apimachinery/pkg/api/equality" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/wait" + fcboot "k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/util/apihelpers" + fq "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing" + fcfmt "k8s.io/apiserver/pkg/util/flowcontrol/format" + "k8s.io/apiserver/pkg/util/flowcontrol/metrics" + fcrequest "k8s.io/apiserver/pkg/util/flowcontrol/request" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" + "k8s.io/klog/v2" + "k8s.io/utils/clock" + + flowcontrol "k8s.io/api/flowcontrol/v1beta3" + flowcontrolapplyconfiguration "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3" + flowcontrolclient "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3" + flowcontrollister "k8s.io/client-go/listers/flowcontrol/v1beta3" +) + +const timeFmt = "2006-01-02T15:04:05.999" + +// This file contains a simple local (to the apiserver) controller +// that digests API Priority and Fairness config objects (FlowSchema +// and PriorityLevelConfiguration) into the data structure that the +// filter uses. At this first level of development this controller +// takes the simplest possible approach: whenever notified of any +// change to any config object, or when any priority level that is +// undesired becomes completely unused, all the config objects are +// read and processed as a whole. + +const ( + // Borrowing among priority levels will be accomplished by periodically + // adjusting the current concurrency limits (CurrentCLs); + // borrowingAdjustmentPeriod is that period. + borrowingAdjustmentPeriod = 10 * time.Second + + // The input to the seat borrowing is smoothed seat demand figures. + // This constant controls the decay rate of that smoothing, + // as described in the comment on the `seatDemandStats` field of `priorityLevelState`. + // The particular number appearing here has the property that half-life + // of that decay is 5 minutes. + // This is a very preliminary guess at a good value and is likely to be tweaked + // once we get some experience with borrowing. + seatDemandSmoothingCoefficient = 0.977 +) + +// The funcs in this package follow the naming convention that the suffix +// "Locked" means the relevant mutex must be locked at the start of each +// call and will be locked upon return. For a configController, the +// suffix "ReadLocked" stipulates a read lock while just "Locked" +// stipulates a full lock. Absence of either suffix means that either +// (a) the lock must NOT be held at call time and will not be held +// upon return or (b) locking is irrelevant. + +// StartFunction begins the process of handling a request. If the +// request gets queued then this function uses the given hashValue as +// the source of entropy as it shuffle-shards the request into a +// queue. The descr1 and descr2 values play no role in the logic but +// appear in log messages. This method does not return until the +// queuing, if any, for this request is done. If `execute` is false +// then `afterExecution` is irrelevant and the request should be +// rejected. Otherwise the request should be executed and +// `afterExecution` must be called exactly once. +type StartFunction func(ctx context.Context, hashValue uint64) (execute bool, afterExecution func()) + +// RequestDigest holds necessary info from request for flow-control +type RequestDigest struct { + RequestInfo *request.RequestInfo + User user.Info +} + +// `*configController` maintains eventual consistency with the API +// objects that configure API Priority and Fairness, and provides a +// procedural interface to the configured behavior. The methods of +// this type and cfgMeal follow the convention that the suffix +// "Locked" means that the caller must hold the configController lock. +type configController struct { + name string // varies in tests of fighting controllers + clock clock.PassiveClock + queueSetFactory fq.QueueSetFactory + reqsGaugeVec metrics.RatioedGaugeVec + execSeatsGaugeVec metrics.RatioedGaugeVec + + // How this controller appears in an ObjectMeta ManagedFieldsEntry.Manager + asFieldManager string + + // Given a boolean indicating whether a FlowSchema's referenced + // PriorityLevelConfig exists, return a boolean indicating whether + // the reference is dangling + foundToDangling func(bool) bool + + // configQueue holds `(interface{})(0)` when the configuration + // objects need to be reprocessed. + configQueue workqueue.RateLimitingInterface + + plLister flowcontrollister.PriorityLevelConfigurationLister + plInformerSynced cache.InformerSynced + + fsLister flowcontrollister.FlowSchemaLister + fsInformerSynced cache.InformerSynced + + flowcontrolClient flowcontrolclient.FlowcontrolV1beta3Interface + + // serverConcurrencyLimit is the limit on the server's total + // number of non-exempt requests being served at once. This comes + // from server configuration. + serverConcurrencyLimit int + + // requestWaitLimit comes from server configuration. + requestWaitLimit time.Duration + + // watchTracker implements the necessary WatchTracker interface. + WatchTracker + + // the most recent update attempts, ordered by increasing age. + // Consumer trims to keep only the last minute's worth of entries. + // The controller uses this to limit itself to at most six updates + // to a given FlowSchema in any minute. + // This may only be accessed from the one and only worker goroutine. + mostRecentUpdates []updateAttempt + + // This must be locked while accessing the later fields. + // A lock for writing is needed + // for writing to any of the following: + // - the flowSchemas field + // - the slice held in the flowSchemas field + // - the priorityLevelStates field + // - the map held in the priorityLevelStates field + // - any field of a priorityLevelState held in that map + lock sync.RWMutex + + // flowSchemas holds the flow schema objects, sorted by increasing + // numerical (decreasing logical) matching precedence. Every + // FlowSchema in this slice is immutable. + flowSchemas apihelpers.FlowSchemaSequence + + // priorityLevelStates maps the PriorityLevelConfiguration object + // name to the state for that level. Every name referenced from a + // member of `flowSchemas` has an entry here. + priorityLevelStates map[string]*priorityLevelState + + // nominalCLSum is the sum of the nominalCL fields in the priorityLevelState records. + // This can exceed serverConcurrencyLimit because of the deliberate rounding up + // in the computation of the nominalCL values. + // This is tracked because it is an input to the allocation adjustment algorithm. + nominalCLSum int +} + +type updateAttempt struct { + timeUpdated time.Time + updatedItems sets.String // FlowSchema names +} + +// priorityLevelState holds the state specific to a priority level. +type priorityLevelState struct { + // the API object or prototype prescribing this level. Nothing + // reached through this pointer is mutable. + pl *flowcontrol.PriorityLevelConfiguration + + // qsCompleter holds the QueueSetCompleter derived from `config` + // and `queues` if config is not exempt, nil otherwise. + qsCompleter fq.QueueSetCompleter + + // The QueueSet for this priority level. This is nil if and only + // if the priority level is exempt. + queues fq.QueueSet + + // quiescing==true indicates that this priority level should be + // removed when its queues have all drained. May be true only if + // queues is non-nil. + quiescing bool + + // number of goroutines between Controller::Match and calling the + // returned StartFunction + numPending int + + // Observers tracking number of requests waiting, executing + reqsGaugePair metrics.RatioedGaugePair + + // Observer of number of seats occupied throughout execution + execSeatsObs metrics.RatioedGauge + + // Integrator of seat demand, reset every CurrentCL adjustment period + seatDemandIntegrator fq.Integrator + + // Gauge of seat demand / nominalCL + seatDemandRatioedGauge metrics.RatioedGauge + + // seatDemandStats is derived from periodically examining the seatDemandIntegrator. + // The average, standard deviation, and high watermark come directly from the integrator. + // envelope = avg + stdDev. + // Periodically smoothed gets replaced with `max(envelope, A*smoothed + (1-A)*envelope)`, + // where A is seatDemandSmoothingCoefficient. + seatDemandStats seatDemandStats + + // nominalCL is the nominal concurrency limit configured in the PriorityLevelConfiguration + nominalCL int + + // minCL is the nominal limit less the lendable amount + minCL int + + //maxCL is the nominal limit plus the amount that may be borrowed + maxCL int + + // currentCL is the dynamically derived concurrency limit to impose for now + currentCL int +} + +type seatDemandStats struct { + avg float64 + stdDev float64 + highWatermark float64 + smoothed float64 +} + +func (stats *seatDemandStats) update(obs fq.IntegratorResults) { + stats.avg = obs.Average + stats.stdDev = obs.Deviation + stats.highWatermark = obs.Max + envelope := obs.Average + obs.Deviation + stats.smoothed = math.Max(envelope, seatDemandSmoothingCoefficient*stats.smoothed+(1-seatDemandSmoothingCoefficient)*envelope) +} + +// NewTestableController is extra flexible to facilitate testing +func newTestableController(config TestableConfig) *configController { + cfgCtlr := &configController{ + name: config.Name, + clock: config.Clock, + queueSetFactory: config.QueueSetFactory, + reqsGaugeVec: config.ReqsGaugeVec, + execSeatsGaugeVec: config.ExecSeatsGaugeVec, + asFieldManager: config.AsFieldManager, + foundToDangling: config.FoundToDangling, + serverConcurrencyLimit: config.ServerConcurrencyLimit, + requestWaitLimit: config.RequestWaitLimit, + flowcontrolClient: config.FlowcontrolClient, + priorityLevelStates: make(map[string]*priorityLevelState), + WatchTracker: NewWatchTracker(), + } + klog.V(2).Infof("NewTestableController %q with serverConcurrencyLimit=%d, requestWaitLimit=%s, name=%s, asFieldManager=%q", cfgCtlr.name, cfgCtlr.serverConcurrencyLimit, cfgCtlr.requestWaitLimit, cfgCtlr.name, cfgCtlr.asFieldManager) + // Start with longish delay because conflicts will be between + // different processes, so take some time to go away. + cfgCtlr.configQueue = workqueue.NewNamedRateLimitingQueue(workqueue.NewItemExponentialFailureRateLimiter(200*time.Millisecond, 8*time.Hour), "priority_and_fairness_config_queue") + // ensure the data structure reflects the mandatory config + cfgCtlr.lockAndDigestConfigObjects(nil, nil) + fci := config.InformerFactory.Flowcontrol().V1beta3() + pli := fci.PriorityLevelConfigurations() + fsi := fci.FlowSchemas() + cfgCtlr.plLister = pli.Lister() + cfgCtlr.plInformerSynced = pli.Informer().HasSynced + cfgCtlr.fsLister = fsi.Lister() + cfgCtlr.fsInformerSynced = fsi.Informer().HasSynced + pli.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + pl := obj.(*flowcontrol.PriorityLevelConfiguration) + klog.V(7).Infof("Triggered API priority and fairness config reloading in %s due to creation of PLC %s", cfgCtlr.name, pl.Name) + cfgCtlr.configQueue.Add(0) + }, + UpdateFunc: func(oldObj, newObj interface{}) { + newPL := newObj.(*flowcontrol.PriorityLevelConfiguration) + oldPL := oldObj.(*flowcontrol.PriorityLevelConfiguration) + if !apiequality.Semantic.DeepEqual(oldPL.Spec, newPL.Spec) { + klog.V(7).Infof("Triggered API priority and fairness config reloading in %s due to spec update of PLC %s", cfgCtlr.name, newPL.Name) + cfgCtlr.configQueue.Add(0) + } else { + klog.V(7).Infof("No trigger API priority and fairness config reloading in %s due to spec non-change of PLC %s", cfgCtlr.name, newPL.Name) + } + }, + DeleteFunc: func(obj interface{}) { + name, _ := cache.DeletionHandlingMetaNamespaceKeyFunc(obj) + klog.V(7).Infof("Triggered API priority and fairness config reloading in %s due to deletion of PLC %s", cfgCtlr.name, name) + cfgCtlr.configQueue.Add(0) + + }}) + fsi.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + fs := obj.(*flowcontrol.FlowSchema) + klog.V(7).Infof("Triggered API priority and fairness config reloading in %s due to creation of FS %s", cfgCtlr.name, fs.Name) + cfgCtlr.configQueue.Add(0) + }, + UpdateFunc: func(oldObj, newObj interface{}) { + newFS := newObj.(*flowcontrol.FlowSchema) + oldFS := oldObj.(*flowcontrol.FlowSchema) + // Changes to either Spec or Status are relevant. The + // concern is that we might, in some future release, want + // different behavior than is implemented now. One of the + // hardest questions is how does an operator roll out the + // new release in a cluster with multiple kube-apiservers + // --- in a way that works no matter what servers crash + // and restart when. If this handler reacts only to + // changes in Spec then we have a scenario in which the + // rollout leaves the old Status in place. The scenario + // ends with this subsequence: deploy the last new server + // before deleting the last old server, and in between + // those two operations the last old server crashes and + // recovers. The chosen solution is making this controller + // insist on maintaining the particular state that it + // establishes. + if !(apiequality.Semantic.DeepEqual(oldFS.Spec, newFS.Spec) && + apiequality.Semantic.DeepEqual(oldFS.Status, newFS.Status)) { + klog.V(7).Infof("Triggered API priority and fairness config reloading in %s due to spec and/or status update of FS %s", cfgCtlr.name, newFS.Name) + cfgCtlr.configQueue.Add(0) + } else { + klog.V(7).Infof("No trigger of API priority and fairness config reloading in %s due to spec and status non-change of FS %s", cfgCtlr.name, newFS.Name) + } + }, + DeleteFunc: func(obj interface{}) { + name, _ := cache.DeletionHandlingMetaNamespaceKeyFunc(obj) + klog.V(7).Infof("Triggered API priority and fairness config reloading in %s due to deletion of FS %s", cfgCtlr.name, name) + cfgCtlr.configQueue.Add(0) + + }}) + return cfgCtlr +} + +func (cfgCtlr *configController) Run(stopCh <-chan struct{}) error { + defer utilruntime.HandleCrash() + + // Let the config worker stop when we are done + defer cfgCtlr.configQueue.ShutDown() + + klog.Info("Starting API Priority and Fairness config controller") + if ok := cache.WaitForCacheSync(stopCh, cfgCtlr.plInformerSynced, cfgCtlr.fsInformerSynced); !ok { + return fmt.Errorf("Never achieved initial sync") + } + + klog.Info("Running API Priority and Fairness config worker") + go wait.Until(cfgCtlr.runWorker, time.Second, stopCh) + + klog.Info("Running API Priority and Fairness periodic rebalancing process") + go wait.Until(cfgCtlr.updateBorrowing, borrowingAdjustmentPeriod, stopCh) + + <-stopCh + klog.Info("Shutting down API Priority and Fairness config worker") + return nil +} + +func (cfgCtlr *configController) updateBorrowing() { + cfgCtlr.lock.Lock() + defer cfgCtlr.lock.Unlock() + cfgCtlr.updateBorrowingLocked(true, cfgCtlr.priorityLevelStates) +} + +func (cfgCtlr *configController) updateBorrowingLocked(setCompleters bool, plStates map[string]*priorityLevelState) { + items := make([]allocProblemItem, 0, len(plStates)) + plNames := make([]string, 0, len(plStates)) + for plName, plState := range plStates { + if plState.pl.Spec.Limited == nil { + continue + } + obs := plState.seatDemandIntegrator.Reset() + plState.seatDemandStats.update(obs) + // Lower bound on this priority level's adjusted concurreny limit is the lesser of: + // - its seat demamd high watermark over the last adjustment period, and + // - its configured concurrency limit. + // BUT: we do not want this to be lower than the lower bound from configuration. + // See KEP-1040 for a more detailed explanation. + minCurrentCL := math.Max(float64(plState.minCL), math.Min(float64(plState.nominalCL), plState.seatDemandStats.highWatermark)) + plNames = append(plNames, plName) + items = append(items, allocProblemItem{ + lowerBound: minCurrentCL, + upperBound: float64(plState.maxCL), + target: math.Max(minCurrentCL, plState.seatDemandStats.smoothed), + }) + } + if len(items) == 0 && cfgCtlr.nominalCLSum > 0 { + klog.ErrorS(nil, "Impossible: no non-exempt priority levels", "plStates", cfgCtlr.priorityLevelStates) + return + } + allocs, fairFrac, err := computeConcurrencyAllocation(cfgCtlr.nominalCLSum, items) + if err != nil { + klog.ErrorS(err, "Unable to derive new concurrency limits", "plNames", plNames, "items", items) + allocs = make([]float64, len(items)) + for idx, plName := range plNames { + plState := plStates[plName] + if plState.pl.Spec.Limited == nil { + continue + } + allocs[idx] = float64(plState.currentCL) + } + } + for idx, plName := range plNames { + plState := plStates[plName] + if plState.pl.Spec.Limited == nil { + continue + } + if setCompleters { + qsCompleter, err := queueSetCompleterForPL(cfgCtlr.queueSetFactory, plState.queues, + plState.pl, cfgCtlr.requestWaitLimit, plState.reqsGaugePair, plState.execSeatsObs, + metrics.NewUnionGauge(plState.seatDemandIntegrator, plState.seatDemandRatioedGauge)) + if err != nil { + klog.ErrorS(err, "Inconceivable! Configuration error in existing priority level", "pl", plState.pl) + continue + } + plState.qsCompleter = qsCompleter + } + currentCL := int(math.Round(float64(allocs[idx]))) + relChange := relDiff(float64(currentCL), float64(plState.currentCL)) + plState.currentCL = currentCL + metrics.NotePriorityLevelConcurrencyAdjustment(plState.pl.Name, plState.seatDemandStats.highWatermark, plState.seatDemandStats.avg, plState.seatDemandStats.stdDev, plState.seatDemandStats.smoothed, float64(items[idx].target), currentCL) + logLevel := klog.Level(4) + if relChange >= 0.05 { + logLevel = 2 + } + klog.V(logLevel).InfoS("Update CurrentCL", "plName", plName, "seatDemandHighWatermark", plState.seatDemandStats.highWatermark, "seatDemandAvg", plState.seatDemandStats.avg, "seatDemandStdev", plState.seatDemandStats.stdDev, "seatDemandSmoothed", plState.seatDemandStats.smoothed, "fairFrac", fairFrac, "currentCL", currentCL, "backstop", err != nil) + plState.queues = plState.qsCompleter.Complete(fq.DispatchingConfig{ConcurrencyLimit: currentCL}) + } + metrics.SetFairFrac(float64(fairFrac)) +} + +// runWorker is the logic of the one and only worker goroutine. We +// limit the number to one in order to obviate explicit +// synchronization around access to `cfgCtlr.mostRecentUpdates`. +func (cfgCtlr *configController) runWorker() { + for cfgCtlr.processNextWorkItem() { + } +} + +// processNextWorkItem works on one entry from the work queue. +// Only invoke this in the one and only worker goroutine. +func (cfgCtlr *configController) processNextWorkItem() bool { + obj, shutdown := cfgCtlr.configQueue.Get() + if shutdown { + return false + } + + func(obj interface{}) { + defer cfgCtlr.configQueue.Done(obj) + specificDelay, err := cfgCtlr.syncOne() + switch { + case err != nil: + klog.Error(err) + cfgCtlr.configQueue.AddRateLimited(obj) + case specificDelay > 0: + cfgCtlr.configQueue.AddAfter(obj, specificDelay) + default: + cfgCtlr.configQueue.Forget(obj) + } + }(obj) + + return true +} + +// syncOne does one full synchronization. It reads all the API +// objects that configure API Priority and Fairness and updates the +// local configController accordingly. +// Only invoke this in the one and only worker goroutine +func (cfgCtlr *configController) syncOne() (specificDelay time.Duration, err error) { + klog.V(5).Infof("%s syncOne at %s", cfgCtlr.name, cfgCtlr.clock.Now().Format(timeFmt)) + all := labels.Everything() + newPLs, err := cfgCtlr.plLister.List(all) + if err != nil { + return 0, fmt.Errorf("unable to list PriorityLevelConfiguration objects: %w", err) + } + newFSs, err := cfgCtlr.fsLister.List(all) + if err != nil { + return 0, fmt.Errorf("unable to list FlowSchema objects: %w", err) + } + return cfgCtlr.digestConfigObjects(newPLs, newFSs) +} + +// cfgMeal is the data involved in the process of digesting the API +// objects that configure API Priority and Fairness. All the config +// objects are digested together, because this is the simplest way to +// cope with the various dependencies between objects. The process of +// digestion is done in four passes over config objects --- three +// passes over PriorityLevelConfigurations and one pass over the +// FlowSchemas --- with the work dvided among the passes according to +// those dependencies. +type cfgMeal struct { + cfgCtlr *configController + + newPLStates map[string]*priorityLevelState + + // The sum of the concurrency shares of the priority levels in the + // new configuration + shareSum float64 + + // These keep track of which mandatory priority level config + // objects have been digested + haveExemptPL, haveCatchAllPL bool + + // Buffered FlowSchema status updates to do. Do them when the + // lock is not held, to avoid a deadlock due to such a request + // provoking a call into this controller while the lock held + // waiting on that request to complete. + fsStatusUpdates []fsStatusUpdate + + maxWaitingRequests, maxExecutingRequests int +} + +// A buffered set of status updates for FlowSchemas +type fsStatusUpdate struct { + flowSchema *flowcontrol.FlowSchema + condition flowcontrol.FlowSchemaCondition + oldValue flowcontrol.FlowSchemaCondition +} + +// digestConfigObjects is given all the API objects that configure +// cfgCtlr and writes its consequent new configState. +// Only invoke this in the one and only worker goroutine +func (cfgCtlr *configController) digestConfigObjects(newPLs []*flowcontrol.PriorityLevelConfiguration, newFSs []*flowcontrol.FlowSchema) (time.Duration, error) { + fsStatusUpdates := cfgCtlr.lockAndDigestConfigObjects(newPLs, newFSs) + var errs []error + currResult := updateAttempt{ + timeUpdated: cfgCtlr.clock.Now(), + updatedItems: sets.String{}, + } + var suggestedDelay time.Duration + for _, fsu := range fsStatusUpdates { + // if we should skip this name, indicate we will need a delay, but continue with other entries + if cfgCtlr.shouldDelayUpdate(fsu.flowSchema.Name) { + if suggestedDelay == 0 { + suggestedDelay = time.Duration(30+rand.Intn(45)) * time.Second + } + continue + } + + // if we are going to issue an update, be sure we track every name we update so we know if we update it too often. + currResult.updatedItems.Insert(fsu.flowSchema.Name) + if klogV := klog.V(4); klogV.Enabled() { + klogV.Infof("%s writing Condition %s to FlowSchema %s, which had ResourceVersion=%s, because its previous value was %s, diff: %s", + cfgCtlr.name, fsu.condition, fsu.flowSchema.Name, fsu.flowSchema.ResourceVersion, fcfmt.Fmt(fsu.oldValue), cmp.Diff(fsu.oldValue, fsu.condition)) + } + + if err := apply(cfgCtlr.flowcontrolClient.FlowSchemas(), fsu, cfgCtlr.asFieldManager); err != nil { + if apierrors.IsNotFound(err) { + // This object has been deleted. A notification is coming + // and nothing more needs to be done here. + klog.V(5).Infof("%s at %s: attempted update of concurrently deleted FlowSchema %s; nothing more needs to be done", cfgCtlr.name, cfgCtlr.clock.Now().Format(timeFmt), fsu.flowSchema.Name) + } else { + errs = append(errs, fmt.Errorf("failed to set a status.condition for FlowSchema %s: %w", fsu.flowSchema.Name, err)) + } + } + } + cfgCtlr.addUpdateResult(currResult) + + return suggestedDelay, utilerrors.NewAggregate(errs) +} + +func apply(client flowcontrolclient.FlowSchemaInterface, fsu fsStatusUpdate, asFieldManager string) error { + applyOptions := metav1.ApplyOptions{FieldManager: asFieldManager, Force: true} + + // the condition field in fsStatusUpdate holds the new condition we want to update. + // TODO: this will break when we have multiple conditions for a flowschema + _, err := client.ApplyStatus(context.TODO(), toFlowSchemaApplyConfiguration(fsu), applyOptions) + return err +} + +func toFlowSchemaApplyConfiguration(fsUpdate fsStatusUpdate) *flowcontrolapplyconfiguration.FlowSchemaApplyConfiguration { + condition := flowcontrolapplyconfiguration.FlowSchemaCondition(). + WithType(fsUpdate.condition.Type). + WithStatus(fsUpdate.condition.Status). + WithReason(fsUpdate.condition.Reason). + WithLastTransitionTime(fsUpdate.condition.LastTransitionTime). + WithMessage(fsUpdate.condition.Message) + + return flowcontrolapplyconfiguration.FlowSchema(fsUpdate.flowSchema.Name). + WithStatus(flowcontrolapplyconfiguration.FlowSchemaStatus(). + WithConditions(condition), + ) +} + +// shouldDelayUpdate checks to see if a flowschema has been updated too often and returns true if a delay is needed. +// Only invoke this in the one and only worker goroutine +func (cfgCtlr *configController) shouldDelayUpdate(flowSchemaName string) bool { + numUpdatesInPastMinute := 0 + oneMinuteAgo := cfgCtlr.clock.Now().Add(-1 * time.Minute) + for idx, update := range cfgCtlr.mostRecentUpdates { + if oneMinuteAgo.After(update.timeUpdated) { + // this and the remaining items are no longer relevant + cfgCtlr.mostRecentUpdates = cfgCtlr.mostRecentUpdates[:idx] + return false + } + if update.updatedItems.Has(flowSchemaName) { + numUpdatesInPastMinute++ + if numUpdatesInPastMinute > 5 { + return true + } + } + } + return false +} + +// addUpdateResult adds the result. It isn't a ring buffer because +// this is small and rate limited. +// Only invoke this in the one and only worker goroutine +func (cfgCtlr *configController) addUpdateResult(result updateAttempt) { + cfgCtlr.mostRecentUpdates = append([]updateAttempt{result}, cfgCtlr.mostRecentUpdates...) +} + +func (cfgCtlr *configController) lockAndDigestConfigObjects(newPLs []*flowcontrol.PriorityLevelConfiguration, newFSs []*flowcontrol.FlowSchema) []fsStatusUpdate { + cfgCtlr.lock.Lock() + defer cfgCtlr.lock.Unlock() + meal := cfgMeal{ + cfgCtlr: cfgCtlr, + newPLStates: make(map[string]*priorityLevelState), + } + + meal.digestNewPLsLocked(newPLs) + meal.digestFlowSchemasLocked(newFSs) + meal.processOldPLsLocked() + + // Supply missing mandatory PriorityLevelConfiguration objects + if !meal.haveExemptPL { + meal.imaginePL(fcboot.MandatoryPriorityLevelConfigurationExempt, cfgCtlr.requestWaitLimit) + } + if !meal.haveCatchAllPL { + meal.imaginePL(fcboot.MandatoryPriorityLevelConfigurationCatchAll, cfgCtlr.requestWaitLimit) + } + + meal.finishQueueSetReconfigsLocked() + + // The new config has been constructed + cfgCtlr.priorityLevelStates = meal.newPLStates + klog.V(5).InfoS("Switched to new API Priority and Fairness configuration", "maxWaitingRequests", meal.maxWaitingRequests, "maxExecutinRequests", meal.maxExecutingRequests) + + metrics.GetWaitingReadonlyConcurrency().SetDenominator(float64(meal.maxWaitingRequests)) + metrics.GetWaitingMutatingConcurrency().SetDenominator(float64(meal.maxWaitingRequests)) + metrics.GetExecutingReadonlyConcurrency().SetDenominator(float64(meal.maxExecutingRequests)) + metrics.GetExecutingMutatingConcurrency().SetDenominator(float64(meal.maxExecutingRequests)) + + return meal.fsStatusUpdates +} + +// Digest the new set of PriorityLevelConfiguration objects. +// Pretend broken ones do not exist. +func (meal *cfgMeal) digestNewPLsLocked(newPLs []*flowcontrol.PriorityLevelConfiguration) { + for _, pl := range newPLs { + state := meal.cfgCtlr.priorityLevelStates[pl.Name] + if state == nil { + labelValues := []string{pl.Name} + state = &priorityLevelState{ + reqsGaugePair: metrics.RatioedGaugeVecPhasedElementPair(meal.cfgCtlr.reqsGaugeVec, 1, 1, labelValues), + execSeatsObs: meal.cfgCtlr.execSeatsGaugeVec.NewForLabelValuesSafe(0, 1, labelValues), + seatDemandIntegrator: fq.NewNamedIntegrator(meal.cfgCtlr.clock, pl.Name), + seatDemandRatioedGauge: metrics.ApiserverSeatDemands.NewForLabelValuesSafe(0, 1, []string{pl.Name}), + } + } + qsCompleter, err := queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, state.queues, + pl, meal.cfgCtlr.requestWaitLimit, state.reqsGaugePair, state.execSeatsObs, + metrics.NewUnionGauge(state.seatDemandIntegrator, state.seatDemandRatioedGauge)) + if err != nil { + klog.Warningf("Ignoring PriorityLevelConfiguration object %s because its spec (%s) is broken: %s", pl.Name, fcfmt.Fmt(pl.Spec), err) + continue + } + meal.newPLStates[pl.Name] = state + state.pl = pl + state.qsCompleter = qsCompleter + if state.quiescing { // it was undesired, but no longer + klog.V(3).Infof("Priority level %q was undesired and has become desired again", pl.Name) + state.quiescing = false + } + if state.pl.Spec.Limited != nil { + meal.shareSum += float64(state.pl.Spec.Limited.NominalConcurrencyShares) + } + meal.haveExemptPL = meal.haveExemptPL || pl.Name == flowcontrol.PriorityLevelConfigurationNameExempt + meal.haveCatchAllPL = meal.haveCatchAllPL || pl.Name == flowcontrol.PriorityLevelConfigurationNameCatchAll + } +} + +// Digest the given FlowSchema objects. Ones that reference a missing +// or broken priority level are not to be passed on to the filter for +// use. We do this before holding over old priority levels so that +// requests stop going to those levels and FlowSchemaStatus values +// reflect this. This function also adds any missing mandatory +// FlowSchema objects. The given objects must all have distinct +// names. +func (meal *cfgMeal) digestFlowSchemasLocked(newFSs []*flowcontrol.FlowSchema) { + fsSeq := make(apihelpers.FlowSchemaSequence, 0, len(newFSs)) + fsMap := make(map[string]*flowcontrol.FlowSchema, len(newFSs)) + var haveExemptFS, haveCatchAllFS bool + for i, fs := range newFSs { + otherFS := fsMap[fs.Name] + if otherFS != nil { + // This client is forbidden to do this. + panic(fmt.Sprintf("Given two FlowSchema objects with the same name: %s and %s", fcfmt.Fmt(otherFS), fcfmt.Fmt(fs))) + } + fsMap[fs.Name] = fs + _, goodPriorityRef := meal.newPLStates[fs.Spec.PriorityLevelConfiguration.Name] + + // Ensure the object's status reflects whether its priority + // level reference is broken. + // + // TODO: consider not even trying if server is not handling + // requests yet. + meal.presyncFlowSchemaStatus(fs, meal.cfgCtlr.foundToDangling(goodPriorityRef), fs.Spec.PriorityLevelConfiguration.Name) + + if !goodPriorityRef { + klog.V(6).Infof("Ignoring FlowSchema %s because of bad priority level reference %q", fs.Name, fs.Spec.PriorityLevelConfiguration.Name) + continue + } + fsSeq = append(fsSeq, newFSs[i]) + haveExemptFS = haveExemptFS || fs.Name == flowcontrol.FlowSchemaNameExempt + haveCatchAllFS = haveCatchAllFS || fs.Name == flowcontrol.FlowSchemaNameCatchAll + } + // sort into the order to be used for matching + sort.Sort(fsSeq) + + // Supply missing mandatory FlowSchemas, in correct position + if !haveExemptFS { + fsSeq = append(apihelpers.FlowSchemaSequence{fcboot.MandatoryFlowSchemaExempt}, fsSeq...) + } + if !haveCatchAllFS { + fsSeq = append(fsSeq, fcboot.MandatoryFlowSchemaCatchAll) + } + + meal.cfgCtlr.flowSchemas = fsSeq + klogV := klog.V(5) + if klogV.Enabled() { + for _, fs := range fsSeq { + klogV.Infof("Using FlowSchema %s", fcfmt.Fmt(fs)) + } + } +} + +// Consider all the priority levels in the previous configuration. +// Keep the ones that are in the new config, supply mandatory +// behavior, or are still busy; for the rest: drop it if it has no +// queues, otherwise start the quiescing process if that has not +// already been started. +func (meal *cfgMeal) processOldPLsLocked() { + for plName, plState := range meal.cfgCtlr.priorityLevelStates { + if meal.newPLStates[plName] != nil { + // Still desired and already updated + continue + } + if plName == flowcontrol.PriorityLevelConfigurationNameExempt && !meal.haveExemptPL || plName == flowcontrol.PriorityLevelConfigurationNameCatchAll && !meal.haveCatchAllPL { + // BTW, we know the Spec has not changed because the + // mandatory objects have immutable Specs + klog.V(3).Infof("Retaining mandatory priority level %q despite lack of API object", plName) + } else { + if plState.queues == nil || plState.numPending == 0 && plState.queues.IsIdle() { + // Either there are no queues or they are done + // draining and no use is coming from another + // goroutine + klog.V(3).Infof("Removing undesired priority level %q (nilQueues=%v), Type=%v", plName, plState.queues == nil, plState.pl.Spec.Type) + continue + } + if !plState.quiescing { + klog.V(3).Infof("Priority level %q became undesired", plName) + plState.quiescing = true + } + } + var err error + plState.qsCompleter, err = queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, plState.queues, + plState.pl, meal.cfgCtlr.requestWaitLimit, plState.reqsGaugePair, plState.execSeatsObs, + metrics.NewUnionGauge(plState.seatDemandIntegrator, plState.seatDemandRatioedGauge)) + if err != nil { + // This can not happen because queueSetCompleterForPL already approved this config + panic(fmt.Sprintf("%s from name=%q spec=%s", err, plName, fcfmt.Fmt(plState.pl.Spec))) + } + if plState.pl.Spec.Limited != nil { + // We deliberately include the lingering priority levels + // here so that their queues get some concurrency and they + // continue to drain. During this interim a lingering + // priority level continues to get a concurrency + // allocation determined by all the share values in the + // regular way. + meal.shareSum += float64(plState.pl.Spec.Limited.NominalConcurrencyShares) + } + meal.haveExemptPL = meal.haveExemptPL || plName == flowcontrol.PriorityLevelConfigurationNameExempt + meal.haveCatchAllPL = meal.haveCatchAllPL || plName == flowcontrol.PriorityLevelConfigurationNameCatchAll + meal.newPLStates[plName] = plState + } +} + +// For all the priority levels of the new config, divide up the +// server's total concurrency limit among them and create/update their +// QueueSets. +func (meal *cfgMeal) finishQueueSetReconfigsLocked() { + for plName, plState := range meal.newPLStates { + if plState.pl.Spec.Limited == nil { + klog.V(5).Infof("Using exempt priority level %q: quiescing=%v", plName, plState.quiescing) + continue + } + + limited := plState.pl.Spec.Limited + // The use of math.Ceil here means that the results might sum + // to a little more than serverConcurrencyLimit but the + // difference will be negligible. + concurrencyLimit := int(math.Ceil(float64(meal.cfgCtlr.serverConcurrencyLimit) * float64(limited.NominalConcurrencyShares) / meal.shareSum)) + var lendableCL, borrowingCL int + if limited.LendablePercent != nil { + lendableCL = int(math.Round(float64(concurrencyLimit) * float64(*limited.LendablePercent) / 100)) + } + if limited.BorrowingLimitPercent != nil { + borrowingCL = int(math.Round(float64(concurrencyLimit) * float64(*limited.BorrowingLimitPercent) / 100)) + } else { + borrowingCL = meal.cfgCtlr.serverConcurrencyLimit + } + metrics.SetPriorityLevelConfiguration(plName, concurrencyLimit, concurrencyLimit-lendableCL, concurrencyLimit+borrowingCL) + plState.seatDemandRatioedGauge.SetDenominator(float64(concurrencyLimit)) + cfgChanged := plState.nominalCL != concurrencyLimit || plState.minCL != concurrencyLimit-lendableCL || plState.maxCL != concurrencyLimit+borrowingCL + plState.nominalCL = concurrencyLimit + plState.minCL = concurrencyLimit - lendableCL + plState.maxCL = concurrencyLimit + borrowingCL + meal.maxExecutingRequests += concurrencyLimit + var waitLimit int + if qCfg := limited.LimitResponse.Queuing; qCfg != nil { + waitLimit = int(qCfg.Queues * qCfg.QueueLengthLimit) + } + meal.maxWaitingRequests += waitLimit + + if plState.queues == nil { + initialCL := concurrencyLimit - lendableCL/2 + klog.V(2).Infof("Introducing queues for priority level %q: config=%s, nominalCL=%d, lendableCL=%d, borrowingCL=%d, currentCL=%d, quiescing=%v (shares=%v, shareSum=%v)", plName, fcfmt.Fmt(plState.pl.Spec), concurrencyLimit, lendableCL, borrowingCL, initialCL, plState.quiescing, plState.pl.Spec.Limited.NominalConcurrencyShares, meal.shareSum) + plState.seatDemandStats = seatDemandStats{} + plState.currentCL = initialCL + } else { + logLevel := klog.Level(5) + if cfgChanged { + logLevel = 2 + } + klog.V(logLevel).Infof("Retaining queues for priority level %q: config=%s, nominalCL=%d, lendableCL=%d, borrowingCL=%d, currentCL=%d, quiescing=%v, numPending=%d (shares=%v, shareSum=%v)", plName, fcfmt.Fmt(plState.pl.Spec), concurrencyLimit, lendableCL, borrowingCL, plState.currentCL, plState.quiescing, plState.numPending, plState.pl.Spec.Limited.NominalConcurrencyShares, meal.shareSum) + } + } + meal.cfgCtlr.nominalCLSum = meal.maxExecutingRequests + meal.cfgCtlr.updateBorrowingLocked(false, meal.newPLStates) +} + +// queueSetCompleterForPL returns an appropriate QueueSetCompleter for the +// given priority level configuration. Returns nil if that config +// does not call for limiting. Returns nil and an error if the given +// object is malformed in a way that is a problem for this package. +func queueSetCompleterForPL(qsf fq.QueueSetFactory, queues fq.QueueSet, pl *flowcontrol.PriorityLevelConfiguration, requestWaitLimit time.Duration, reqsIntPair metrics.RatioedGaugePair, execSeatsObs metrics.RatioedGauge, seatDemandGauge metrics.Gauge) (fq.QueueSetCompleter, error) { + if (pl.Spec.Type == flowcontrol.PriorityLevelEnablementExempt) != (pl.Spec.Limited == nil) { + return nil, errors.New("broken union structure at the top") + } + if (pl.Spec.Type == flowcontrol.PriorityLevelEnablementExempt) != (pl.Name == flowcontrol.PriorityLevelConfigurationNameExempt) { + // This package does not attempt to cope with a priority level dynamically switching between exempt and not. + return nil, errors.New("non-alignment between name and type") + } + if pl.Spec.Limited == nil { + return nil, nil + } + if (pl.Spec.Limited.LimitResponse.Type == flowcontrol.LimitResponseTypeReject) != (pl.Spec.Limited.LimitResponse.Queuing == nil) { + return nil, errors.New("broken union structure for limit response") + } + qcAPI := pl.Spec.Limited.LimitResponse.Queuing + qcQS := fq.QueuingConfig{Name: pl.Name} + if qcAPI != nil { + qcQS = fq.QueuingConfig{Name: pl.Name, + DesiredNumQueues: int(qcAPI.Queues), + QueueLengthLimit: int(qcAPI.QueueLengthLimit), + HandSize: int(qcAPI.HandSize), + RequestWaitLimit: requestWaitLimit, + } + } + var qsc fq.QueueSetCompleter + var err error + if queues != nil { + qsc, err = queues.BeginConfigChange(qcQS) + } else { + qsc, err = qsf.BeginConstruction(qcQS, reqsIntPair, execSeatsObs, seatDemandGauge) + } + if err != nil { + err = fmt.Errorf("priority level %q has QueuingConfiguration %#+v, which is invalid: %w", pl.Name, qcAPI, err) + } + return qsc, err +} + +func (meal *cfgMeal) presyncFlowSchemaStatus(fs *flowcontrol.FlowSchema, isDangling bool, plName string) { + danglingCondition := apihelpers.GetFlowSchemaConditionByType(fs, flowcontrol.FlowSchemaConditionDangling) + if danglingCondition == nil { + danglingCondition = &flowcontrol.FlowSchemaCondition{ + Type: flowcontrol.FlowSchemaConditionDangling, + } + } + desiredStatus := flowcontrol.ConditionFalse + var desiredReason, desiredMessage string + if isDangling { + desiredStatus = flowcontrol.ConditionTrue + desiredReason = "NotFound" + desiredMessage = fmt.Sprintf("This FlowSchema references the PriorityLevelConfiguration object named %q but there is no such object", plName) + } else { + desiredReason = "Found" + desiredMessage = fmt.Sprintf("This FlowSchema references the PriorityLevelConfiguration object named %q and it exists", plName) + } + if danglingCondition.Status == desiredStatus && danglingCondition.Reason == desiredReason && danglingCondition.Message == desiredMessage { + return + } + now := meal.cfgCtlr.clock.Now() + meal.fsStatusUpdates = append(meal.fsStatusUpdates, fsStatusUpdate{ + flowSchema: fs, + condition: flowcontrol.FlowSchemaCondition{ + Type: flowcontrol.FlowSchemaConditionDangling, + Status: desiredStatus, + LastTransitionTime: metav1.NewTime(now), + Reason: desiredReason, + Message: desiredMessage, + }, + oldValue: *danglingCondition}) +} + +// imaginePL adds a priority level based on one of the mandatory ones +// that does not actually exist (right now) as a real API object. +func (meal *cfgMeal) imaginePL(proto *flowcontrol.PriorityLevelConfiguration, requestWaitLimit time.Duration) { + klog.V(3).Infof("No %s PriorityLevelConfiguration found, imagining one", proto.Name) + labelValues := []string{proto.Name} + reqsGaugePair := metrics.RatioedGaugeVecPhasedElementPair(meal.cfgCtlr.reqsGaugeVec, 1, 1, labelValues) + execSeatsObs := meal.cfgCtlr.execSeatsGaugeVec.NewForLabelValuesSafe(0, 1, labelValues) + seatDemandIntegrator := fq.NewNamedIntegrator(meal.cfgCtlr.clock, proto.Name) + seatDemandRatioedGauge := metrics.ApiserverSeatDemands.NewForLabelValuesSafe(0, 1, []string{proto.Name}) + qsCompleter, err := queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, nil, proto, + requestWaitLimit, reqsGaugePair, execSeatsObs, + metrics.NewUnionGauge(seatDemandIntegrator, seatDemandRatioedGauge)) + if err != nil { + // This can not happen because proto is one of the mandatory + // objects and these are not erroneous + panic(err) + } + meal.newPLStates[proto.Name] = &priorityLevelState{ + pl: proto, + qsCompleter: qsCompleter, + reqsGaugePair: reqsGaugePair, + execSeatsObs: execSeatsObs, + seatDemandIntegrator: seatDemandIntegrator, + seatDemandRatioedGauge: seatDemandRatioedGauge, + } + if proto.Spec.Limited != nil { + meal.shareSum += float64(proto.Spec.Limited.NominalConcurrencyShares) + } +} + +type immediateRequest struct{} + +func (immediateRequest) Finish(execute func()) bool { + execute() + return false +} + +// startRequest classifies and, if appropriate, enqueues the request. +// Returns a nil Request if and only if the request is to be rejected. +// The returned bool indicates whether the request is exempt from +// limitation. The startWaitingTime is when the request started +// waiting in its queue, or `Time{}` if this did not happen. +func (cfgCtlr *configController) startRequest(ctx context.Context, rd RequestDigest, + noteFn func(fs *flowcontrol.FlowSchema, pl *flowcontrol.PriorityLevelConfiguration, flowDistinguisher string), + workEstimator func() fcrequest.WorkEstimate, + queueNoteFn fq.QueueNoteFn) (fs *flowcontrol.FlowSchema, pl *flowcontrol.PriorityLevelConfiguration, isExempt bool, req fq.Request, startWaitingTime time.Time) { + klog.V(7).Infof("startRequest(%#+v)", rd) + cfgCtlr.lock.RLock() + defer cfgCtlr.lock.RUnlock() + var selectedFlowSchema, catchAllFlowSchema *flowcontrol.FlowSchema + for _, fs := range cfgCtlr.flowSchemas { + if matchesFlowSchema(rd, fs) { + selectedFlowSchema = fs + break + } + if fs.Name == flowcontrol.FlowSchemaNameCatchAll { + catchAllFlowSchema = fs + } + } + if selectedFlowSchema == nil { + // This should never happen. If the requestDigest's User is a part of + // system:authenticated or system:unauthenticated, the catch-all flow + // schema should match it. However, if that invariant somehow fails, + // fallback to the catch-all flow schema anyway. + if catchAllFlowSchema == nil { + // This should absolutely never, ever happen! APF guarantees two + // undeletable flow schemas at all times: an exempt flow schema and a + // catch-all flow schema. + panic(fmt.Sprintf("no fallback catch-all flow schema found for request %#+v and user %#+v", rd.RequestInfo, rd.User)) + } + selectedFlowSchema = catchAllFlowSchema + klog.Warningf("no match found for request %#+v and user %#+v; selecting catchAll=%s as fallback flow schema", rd.RequestInfo, rd.User, fcfmt.Fmt(selectedFlowSchema)) + } + plName := selectedFlowSchema.Spec.PriorityLevelConfiguration.Name + plState := cfgCtlr.priorityLevelStates[plName] + if plState.pl.Spec.Type == flowcontrol.PriorityLevelEnablementExempt { + noteFn(selectedFlowSchema, plState.pl, "") + klog.V(7).Infof("startRequest(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, immediate", rd, selectedFlowSchema.Name, selectedFlowSchema.Spec.DistinguisherMethod, plName) + return selectedFlowSchema, plState.pl, true, immediateRequest{}, time.Time{} + } + var numQueues int32 + if plState.pl.Spec.Limited.LimitResponse.Type == flowcontrol.LimitResponseTypeQueue { + numQueues = plState.pl.Spec.Limited.LimitResponse.Queuing.Queues + } + var flowDistinguisher string + var hashValue uint64 + if numQueues > 1 { + flowDistinguisher = computeFlowDistinguisher(rd, selectedFlowSchema.Spec.DistinguisherMethod) + hashValue = hashFlowID(selectedFlowSchema.Name, flowDistinguisher) + } + + noteFn(selectedFlowSchema, plState.pl, flowDistinguisher) + workEstimate := workEstimator() + + startWaitingTime = cfgCtlr.clock.Now() + klog.V(7).Infof("startRequest(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, numQueues=%d", rd, selectedFlowSchema.Name, selectedFlowSchema.Spec.DistinguisherMethod, plName, numQueues) + req, idle := plState.queues.StartRequest(ctx, &workEstimate, hashValue, flowDistinguisher, selectedFlowSchema.Name, rd.RequestInfo, rd.User, queueNoteFn) + if idle { + cfgCtlr.maybeReapReadLocked(plName, plState) + } + return selectedFlowSchema, plState.pl, false, req, startWaitingTime +} + +// maybeReap will remove the last internal traces of the named +// priority level if it has no more use. Call this after getting a +// clue that the given priority level is undesired and idle. +func (cfgCtlr *configController) maybeReap(plName string) { + cfgCtlr.lock.RLock() + defer cfgCtlr.lock.RUnlock() + plState := cfgCtlr.priorityLevelStates[plName] + if plState == nil { + klog.V(7).Infof("plName=%s, plState==nil", plName) + return + } + if plState.queues == nil { + klog.V(7).Infof("plName=%s, plState.queues==nil", plName) + return + } + useless := plState.quiescing && plState.numPending == 0 && plState.queues.IsIdle() + klog.V(7).Infof("plState.quiescing=%v, plState.numPending=%d, useless=%v", plState.quiescing, plState.numPending, useless) + if !useless { + return + } + klog.V(3).Infof("Triggered API priority and fairness config reloading because priority level %s is undesired and idle", plName) + cfgCtlr.configQueue.Add(0) +} + +// maybeReapLocked requires the cfgCtlr's lock to already be held and +// will remove the last internal traces of the named priority level if +// it has no more use. Call this if both (1) plState.queues is +// non-nil and reported being idle, and (2) cfgCtlr's lock has not +// been released since then. +func (cfgCtlr *configController) maybeReapReadLocked(plName string, plState *priorityLevelState) { + if !(plState.quiescing && plState.numPending == 0) { + return + } + klog.V(3).Infof("Triggered API priority and fairness config reloading because priority level %s is undesired and idle", plName) + cfgCtlr.configQueue.Add(0) +} + +// computeFlowDistinguisher extracts the flow distinguisher according to the given method +func computeFlowDistinguisher(rd RequestDigest, method *flowcontrol.FlowDistinguisherMethod) string { + if method == nil { + return "" + } + switch method.Type { + case flowcontrol.FlowDistinguisherMethodByUserType: + return rd.User.GetName() + case flowcontrol.FlowDistinguisherMethodByNamespaceType: + return rd.RequestInfo.Namespace + default: + // this line shall never reach + panic("invalid flow-distinguisher method") + } +} + +func hashFlowID(fsName, fDistinguisher string) uint64 { + hash := sha256.New() + var sep = [1]byte{0} + hash.Write([]byte(fsName)) + hash.Write(sep[:]) + hash.Write([]byte(fDistinguisher)) + var sum [32]byte + hash.Sum(sum[:0]) + return binary.LittleEndian.Uint64(sum[:8]) +} + +func relDiff(x, y float64) float64 { + diff := math.Abs(x - y) + den := math.Max(math.Abs(x), math.Abs(y)) + if den == 0 { + return 0 + } + return diff / den +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller_debug.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller_debug.go new file mode 100644 index 0000000000..0b9bc02f92 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller_debug.go @@ -0,0 +1,293 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package flowcontrol + +import ( + "fmt" + "io" + "net/http" + "sort" + "strconv" + "strings" + "text/tabwriter" + "time" + + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apiserver/pkg/server/mux" +) + +const ( + queryIncludeRequestDetails = "includeRequestDetails" +) + +func (cfgCtlr *configController) Install(c *mux.PathRecorderMux) { + // TODO(yue9944882): handle "Accept" header properly + // debugging dumps a CSV content for three levels of granularity + // 1. row per priority-level + c.UnlistedHandleFunc("/debug/api_priority_and_fairness/dump_priority_levels", cfgCtlr.dumpPriorityLevels) + // 2. row per queue + c.UnlistedHandleFunc("/debug/api_priority_and_fairness/dump_queues", cfgCtlr.dumpQueues) + // 3. row per request + c.UnlistedHandleFunc("/debug/api_priority_and_fairness/dump_requests", cfgCtlr.dumpRequests) +} + +func (cfgCtlr *configController) dumpPriorityLevels(w http.ResponseWriter, r *http.Request) { + cfgCtlr.lock.Lock() + defer cfgCtlr.lock.Unlock() + tabWriter := tabwriter.NewWriter(w, 8, 0, 1, ' ', 0) + columnHeaders := []string{ + "PriorityLevelName", // 1 + "ActiveQueues", // 2 + "IsIdle", // 3 + "IsQuiescing", // 4 + "WaitingRequests", // 5 + "ExecutingRequests", // 6 + "DispatchedRequests", // 7 + "RejectedRequests", // 8 + "TimedoutRequests", // 9 + "CancelledRequests", // 10 + } + tabPrint(tabWriter, rowForHeaders(columnHeaders)) + endLine(tabWriter) + plNames := make([]string, 0, len(cfgCtlr.priorityLevelStates)) + for plName := range cfgCtlr.priorityLevelStates { + plNames = append(plNames, plName) + } + sort.Strings(plNames) + for i := range plNames { + plState, ok := cfgCtlr.priorityLevelStates[plNames[i]] + if !ok { + continue + } + + if plState.queues == nil { + tabPrint(tabWriter, row( + plState.pl.Name, // 1 + "", // 2 + "", // 3 + "", // 4 + "", // 5 + "", // 6 + "", // 7 + "", // 8 + "", // 9 + "", // 10 + )) + endLine(tabWriter) + continue + } + queueSetDigest := plState.queues.Dump(false) + activeQueueNum := 0 + for _, q := range queueSetDigest.Queues { + if len(q.Requests) > 0 { + activeQueueNum++ + } + } + + tabPrint(tabWriter, rowForPriorityLevel( + plState.pl.Name, // 1 + activeQueueNum, // 2 + plState.queues.IsIdle(), // 3 + plState.quiescing, // 4 + queueSetDigest.Waiting, // 5 + queueSetDigest.Executing, // 6 + queueSetDigest.Dispatched, // 7 + queueSetDigest.Rejected, // 8 + queueSetDigest.Timedout, // 9 + queueSetDigest.Cancelled, // 10 + )) + endLine(tabWriter) + } + runtime.HandleError(tabWriter.Flush()) +} + +func (cfgCtlr *configController) dumpQueues(w http.ResponseWriter, r *http.Request) { + cfgCtlr.lock.Lock() + defer cfgCtlr.lock.Unlock() + tabWriter := tabwriter.NewWriter(w, 8, 0, 1, ' ', 0) + columnHeaders := []string{ + "PriorityLevelName", // 1 + "Index", // 2 + "PendingRequests", // 3 + "ExecutingRequests", // 4 + "SeatsInUse", // 5 + "NextDispatchR", // 6 + "InitialSeatsSum", // 7 + "MaxSeatsSum", // 8 + "TotalWorkSum", // 9 + } + tabPrint(tabWriter, rowForHeaders(columnHeaders)) + endLine(tabWriter) + for _, plState := range cfgCtlr.priorityLevelStates { + if plState.queues == nil { + tabPrint(tabWriter, row( + plState.pl.Name, // 1 + "", // 2 + "", // 3 + "", // 4 + "", // 5 + "", // 6 + "", // 7 + "", // 8 + "", // 9 + )) + endLine(tabWriter) + continue + } + queueSetDigest := plState.queues.Dump(false) + for i, q := range queueSetDigest.Queues { + tabPrint(tabWriter, row( + plState.pl.Name, // 1 - "PriorityLevelName" + strconv.Itoa(i), // 2 - "Index" + strconv.Itoa(len(q.Requests)), // 3 - "PendingRequests" + strconv.Itoa(q.ExecutingRequests), // 4 - "ExecutingRequests" + strconv.Itoa(q.SeatsInUse), // 5 - "SeatsInUse" + q.NextDispatchR, // 6 - "NextDispatchR" + strconv.Itoa(q.QueueSum.InitialSeatsSum), // 7 - "InitialSeatsSum" + strconv.Itoa(q.QueueSum.MaxSeatsSum), // 8 - "MaxSeatsSum" + q.QueueSum.TotalWorkSum, // 9 - "TotalWorkSum" + )) + endLine(tabWriter) + } + } + runtime.HandleError(tabWriter.Flush()) +} + +func (cfgCtlr *configController) dumpRequests(w http.ResponseWriter, r *http.Request) { + cfgCtlr.lock.Lock() + defer cfgCtlr.lock.Unlock() + + includeRequestDetails := len(r.URL.Query().Get(queryIncludeRequestDetails)) > 0 + + tabWriter := tabwriter.NewWriter(w, 8, 0, 1, ' ', 0) + tabPrint(tabWriter, rowForHeaders([]string{ + "PriorityLevelName", // 1 + "FlowSchemaName", // 2 + "QueueIndex", // 3 + "RequestIndexInQueue", // 4 + "FlowDistingsher", // 5 + "ArriveTime", // 6 + "InitialSeats", // 7 + "FinalSeats", // 8 + "AdditionalLatency", // 9 + })) + if includeRequestDetails { + continueLine(tabWriter) + tabPrint(tabWriter, rowForHeaders([]string{ + "UserName", // 10 + "Verb", // 11 + "APIPath", // 12 + "Namespace", // 13 + "Name", // 14 + "APIVersion", // 15 + "Resource", // 16 + "SubResource", // 17 + })) + } + endLine(tabWriter) + for _, plState := range cfgCtlr.priorityLevelStates { + if plState.queues == nil { + continue + } + queueSetDigest := plState.queues.Dump(includeRequestDetails) + for iq, q := range queueSetDigest.Queues { + for ir, r := range q.Requests { + tabPrint(tabWriter, row( + plState.pl.Name, // 1 + r.MatchedFlowSchema, // 2 + strconv.Itoa(iq), // 3 + strconv.Itoa(ir), // 4 + r.FlowDistinguisher, // 5 + r.ArriveTime.UTC().Format(time.RFC3339Nano), // 6 + strconv.Itoa(int(r.WorkEstimate.InitialSeats)), // 7 + strconv.Itoa(int(r.WorkEstimate.FinalSeats)), // 8 + r.WorkEstimate.AdditionalLatency.String(), // 9 + )) + if includeRequestDetails { + continueLine(tabWriter) + tabPrint(tabWriter, rowForRequestDetails( + r.UserName, // 10 + r.RequestInfo.Verb, // 11 + r.RequestInfo.Path, // 12 + r.RequestInfo.Namespace, // 13 + r.RequestInfo.Name, // 14 + schema.GroupVersion{ + Group: r.RequestInfo.APIGroup, + Version: r.RequestInfo.APIVersion, + }.String(), // 15 + r.RequestInfo.Resource, // 16 + r.RequestInfo.Subresource, // 17 + )) + } + endLine(tabWriter) + } + } + } + runtime.HandleError(tabWriter.Flush()) +} + +func tabPrint(w io.Writer, row string) { + _, err := fmt.Fprint(w, row) + runtime.HandleError(err) +} + +func continueLine(w io.Writer) { + _, err := fmt.Fprint(w, ",\t") + runtime.HandleError(err) +} +func endLine(w io.Writer) { + _, err := fmt.Fprint(w, "\n") + runtime.HandleError(err) +} + +func rowForHeaders(headers []string) string { + return row(headers...) +} + +func rowForPriorityLevel(plName string, activeQueues int, isIdle, isQuiescing bool, waitingRequests, executingRequests int, + dispatchedReqeusts, rejectedRequests, timedoutRequests, cancelledRequests int) string { + return row( + plName, + strconv.Itoa(activeQueues), + strconv.FormatBool(isIdle), + strconv.FormatBool(isQuiescing), + strconv.Itoa(waitingRequests), + strconv.Itoa(executingRequests), + strconv.Itoa(dispatchedReqeusts), + strconv.Itoa(rejectedRequests), + strconv.Itoa(timedoutRequests), + strconv.Itoa(cancelledRequests), + ) +} + +func rowForRequestDetails(username, verb, path, namespace, name, apiVersion, resource, subResource string) string { + return row( + username, + verb, + path, + namespace, + name, + apiVersion, + resource, + subResource, + ) +} + +func row(columns ...string) string { + return strings.Join(columns, ",\t") +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_filter.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_filter.go new file mode 100644 index 0000000000..2929048ecc --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_filter.go @@ -0,0 +1,204 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package flowcontrol + +import ( + "context" + "strconv" + "time" + + endpointsrequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/server/httplog" + "k8s.io/apiserver/pkg/server/mux" + fq "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing" + "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock" + fqs "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset" + "k8s.io/apiserver/pkg/util/flowcontrol/metrics" + fcrequest "k8s.io/apiserver/pkg/util/flowcontrol/request" + kubeinformers "k8s.io/client-go/informers" + "k8s.io/klog/v2" + "k8s.io/utils/clock" + + flowcontrol "k8s.io/api/flowcontrol/v1beta3" + flowcontrolclient "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3" +) + +// ConfigConsumerAsFieldManager is how the config consuminng +// controller appears in an ObjectMeta ManagedFieldsEntry.Manager +const ConfigConsumerAsFieldManager = "api-priority-and-fairness-config-consumer-v1" + +// Interface defines how the API Priority and Fairness filter interacts with the underlying system. +type Interface interface { + // Handle takes care of queuing and dispatching a request + // characterized by the given digest. The given `noteFn` will be + // invoked with the results of request classification. + // The given `workEstimator` is called, if at all, after noteFn. + // `workEstimator` will be invoked only when the request + // is classified as non 'exempt'. + // 'workEstimator', when invoked, must return the + // work parameters for the request. + // If the request is queued then `queueNoteFn` will be called twice, + // first with `true` and then with `false`; otherwise + // `queueNoteFn` will not be called at all. If Handle decides + // that the request should be executed then `execute()` will be + // invoked once to execute the request; otherwise `execute()` will + // not be invoked. + // Handle() should never return while execute() is running, even if + // ctx is cancelled or times out. + Handle(ctx context.Context, + requestDigest RequestDigest, + noteFn func(fs *flowcontrol.FlowSchema, pl *flowcontrol.PriorityLevelConfiguration, flowDistinguisher string), + workEstimator func() fcrequest.WorkEstimate, + queueNoteFn fq.QueueNoteFn, + execFn func(), + ) + + // Run monitors config objects from the main apiservers and causes + // any needed changes to local behavior. This method ceases + // activity and returns after the given channel is closed. + Run(stopCh <-chan struct{}) error + + // Install installs debugging endpoints to the web-server. + Install(c *mux.PathRecorderMux) + + // WatchTracker provides the WatchTracker interface. + WatchTracker +} + +// This request filter implements https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/1040-priority-and-fairness/README.md + +// New creates a new instance to implement API priority and fairness +func New( + informerFactory kubeinformers.SharedInformerFactory, + flowcontrolClient flowcontrolclient.FlowcontrolV1beta3Interface, + serverConcurrencyLimit int, + requestWaitLimit time.Duration, +) Interface { + clk := eventclock.Real{} + return NewTestable(TestableConfig{ + Name: "Controller", + Clock: clk, + AsFieldManager: ConfigConsumerAsFieldManager, + FoundToDangling: func(found bool) bool { return !found }, + InformerFactory: informerFactory, + FlowcontrolClient: flowcontrolClient, + ServerConcurrencyLimit: serverConcurrencyLimit, + RequestWaitLimit: requestWaitLimit, + ReqsGaugeVec: metrics.PriorityLevelConcurrencyGaugeVec, + ExecSeatsGaugeVec: metrics.PriorityLevelExecutionSeatsGaugeVec, + QueueSetFactory: fqs.NewQueueSetFactory(clk), + }) +} + +// TestableConfig carries the parameters to an implementation that is testable +type TestableConfig struct { + // Name of the controller + Name string + + // Clock to use in timing deliberate delays + Clock clock.PassiveClock + + // AsFieldManager is the string to use in the metadata for + // server-side apply. Normally this is + // `ConfigConsumerAsFieldManager`. This is exposed as a parameter + // so that a test of competing controllers can supply different + // values. + AsFieldManager string + + // FoundToDangling maps the boolean indicating whether a + // FlowSchema's referenced PLC exists to the boolean indicating + // that FlowSchema's status should indicate a dangling reference. + // This is a parameter so that we can write tests of what happens + // when servers disagree on that bit of Status. + FoundToDangling func(bool) bool + + // InformerFactory to use in building the controller + InformerFactory kubeinformers.SharedInformerFactory + + // FlowcontrolClient to use for manipulating config objects + FlowcontrolClient flowcontrolclient.FlowcontrolV1beta3Interface + + // ServerConcurrencyLimit for the controller to enforce + ServerConcurrencyLimit int + + // RequestWaitLimit configured on the server + RequestWaitLimit time.Duration + + // GaugeVec for metrics about requests, broken down by phase and priority_level + ReqsGaugeVec metrics.RatioedGaugeVec + + // RatioedGaugePairVec for metrics about seats occupied by all phases of execution + ExecSeatsGaugeVec metrics.RatioedGaugeVec + + // QueueSetFactory for the queuing implementation + QueueSetFactory fq.QueueSetFactory +} + +// NewTestable is extra flexible to facilitate testing +func NewTestable(config TestableConfig) Interface { + return newTestableController(config) +} + +func (cfgCtlr *configController) Handle(ctx context.Context, requestDigest RequestDigest, + noteFn func(fs *flowcontrol.FlowSchema, pl *flowcontrol.PriorityLevelConfiguration, flowDistinguisher string), + workEstimator func() fcrequest.WorkEstimate, + queueNoteFn fq.QueueNoteFn, + execFn func()) { + fs, pl, isExempt, req, startWaitingTime := cfgCtlr.startRequest(ctx, requestDigest, noteFn, workEstimator, queueNoteFn) + queued := startWaitingTime != time.Time{} + if req == nil { + if queued { + observeQueueWaitTime(ctx, pl.Name, fs.Name, strconv.FormatBool(req != nil), cfgCtlr.clock.Since(startWaitingTime)) + } + klog.V(7).Infof("Handle(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, isExempt=%v, reject", requestDigest, fs.Name, fs.Spec.DistinguisherMethod, pl.Name, isExempt) + return + } + klog.V(7).Infof("Handle(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, isExempt=%v, queued=%v", requestDigest, fs.Name, fs.Spec.DistinguisherMethod, pl.Name, isExempt, queued) + var executed bool + idle, panicking := true, true + defer func() { + klog.V(7).Infof("Handle(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, isExempt=%v, queued=%v, Finish() => panicking=%v idle=%v", + requestDigest, fs.Name, fs.Spec.DistinguisherMethod, pl.Name, isExempt, queued, panicking, idle) + if idle { + cfgCtlr.maybeReap(pl.Name) + } + }() + idle = req.Finish(func() { + if queued { + observeQueueWaitTime(ctx, pl.Name, fs.Name, strconv.FormatBool(req != nil), cfgCtlr.clock.Since(startWaitingTime)) + } + metrics.AddDispatch(ctx, pl.Name, fs.Name) + fqs.OnRequestDispatched(req) + executed = true + startExecutionTime := cfgCtlr.clock.Now() + defer func() { + executionTime := cfgCtlr.clock.Since(startExecutionTime) + httplog.AddKeyValue(ctx, "apf_execution_time", executionTime) + metrics.ObserveExecutionDuration(ctx, pl.Name, fs.Name, executionTime) + }() + execFn() + }) + if queued && !executed { + observeQueueWaitTime(ctx, pl.Name, fs.Name, strconv.FormatBool(req != nil), cfgCtlr.clock.Since(startWaitingTime)) + } + panicking = false +} + +func observeQueueWaitTime(ctx context.Context, priorityLevelName, flowSchemaName, execute string, waitTime time.Duration) { + metrics.ObserveWaitingDuration(ctx, priorityLevelName, flowSchemaName, execute, waitTime) + endpointsrequest.TrackAPFQueueWaitLatency(ctx, waitTime) +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/conc_alloc.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/conc_alloc.go new file mode 100644 index 0000000000..904f4fce2f --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/conc_alloc.go @@ -0,0 +1,257 @@ +/* +Copyright 2022 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 flowcontrol + +import ( + "errors" + "fmt" + "math" + "sort" +) + +// allocProblemItem is one of the classes to which computeConcurrencyAllocation should make an allocation +type allocProblemItem struct { + target float64 + lowerBound float64 + upperBound float64 +} + +// relativeAllocItem is like allocProblemItem but with target avoiding zero and the bounds divided by the target +type relativeAllocItem struct { + target float64 + relativeLowerBound float64 + relativeUpperBound float64 +} + +// relativeAllocProblem collects together all the classes and holds the result of sorting by increasing bounds. +// For J <= K, ascendingIndices[J] identifies a bound that is <= the one of ascendingIndices[K]. +// When ascendingIndices[J] = 2*N + 0, this identifies the lower bound of items[N]. +// When ascendingIndices[J] = 2*N + 1, this identifies the upper bound of items[N]. +type relativeAllocProblem struct { + items []relativeAllocItem + ascendingIndices []int +} + +// initIndices fills in ascendingIndices and sorts them +func (rap *relativeAllocProblem) initIndices() *relativeAllocProblem { + rap.ascendingIndices = make([]int, len(rap.items)*2) + for idx := 0; idx < len(rap.ascendingIndices); idx++ { + rap.ascendingIndices[idx] = idx + } + sort.Sort(rap) + return rap +} + +func (rap *relativeAllocProblem) getItemIndex(idx int) (int, bool) { + packedIndex := rap.ascendingIndices[idx] + itemIndex := packedIndex / 2 + return itemIndex, packedIndex == itemIndex*2 +} + +// decode(J) returns the bound associated with ascendingIndices[J], the associated items index, +// and a bool indicating whether the bound is the item's lower bound. +func (rap *relativeAllocProblem) decode(idx int) (float64, int, bool) { + itemIdx, lower := rap.getItemIndex(idx) + if lower { + return rap.items[itemIdx].relativeLowerBound, itemIdx, lower + } + return rap.items[itemIdx].relativeUpperBound, itemIdx, lower +} + +func (rap *relativeAllocProblem) getProportion(idx int) float64 { + prop, _, _ := rap.decode(idx) + return prop +} + +func (rap *relativeAllocProblem) Len() int { return len(rap.items) * 2 } + +func (rap *relativeAllocProblem) Less(i, j int) bool { + return rap.getProportion(i) < rap.getProportion(j) +} + +func (rap *relativeAllocProblem) Swap(i, j int) { + rap.ascendingIndices[i], rap.ascendingIndices[j] = rap.ascendingIndices[j], rap.ascendingIndices[i] +} + +// minMax records the minimum and maximum value seen while scanning a set of numbers +type minMax struct { + min float64 + max float64 +} + +// note scans one more number +func (mm *minMax) note(x float64) { + mm.min = math.Min(mm.min, x) + mm.max = math.Max(mm.max, x) +} + +const MinTarget = 0.001 +const epsilon = 0.0000001 + +// computeConcurrencyAllocation returns the unique `allocs []float64`, and +// an associated `fairProp float64`, that jointly have +// all of the following properties (to the degree that floating point calculations allow) +// if possible otherwise returns an error saying why it is impossible. +// `allocs` sums to `requiredSum`. +// For each J in [0, len(classes)): +// 1. `classes[J].lowerBound <= allocs[J] <= classes[J].upperBound` and +// 2. exactly one of the following is true: +// 2a. `allocs[J] == fairProp * classes[J].target`, +// 2b. `allocs[J] == classes[J].lowerBound && classes[J].lowerBound > fairProp * classes[J].target`, or +// 2c. `allocs[J] == classes[J].upperBound && classes[J].upperBound < fairProp * classes[J].target`. +// +// Each allocProblemItem is required to have `target >= lowerBound >= 0` and `upperBound >= lowerBound`. +// A target smaller than MinTarget is treated as if it were MinTarget. +func computeConcurrencyAllocation(requiredSum int, classes []allocProblemItem) ([]float64, float64, error) { + if requiredSum < 0 { + return nil, 0, errors.New("negative sums are not supported") + } + requiredSumF := float64(requiredSum) + var lowSum, highSum, targetSum float64 + ubRange := minMax{min: float64(math.MaxFloat32)} + lbRange := minMax{min: float64(math.MaxFloat32)} + relativeItems := make([]relativeAllocItem, len(classes)) + for idx, item := range classes { + target := item.target + if item.lowerBound < 0 { + return nil, 0, fmt.Errorf("lower bound %d is %v but negative lower bounds are not allowed", idx, item.lowerBound) + } + if target < item.lowerBound { + return nil, 0, fmt.Errorf("target %d is %v, which is below its lower bound of %v", idx, target, item.lowerBound) + } + if item.upperBound < item.lowerBound { + return nil, 0, fmt.Errorf("upper bound %d is %v but should not be less than the lower bound %v", idx, item.upperBound, item.lowerBound) + } + if target < MinTarget { + // tweak this to a non-zero value so avoid dividing by zero + target = MinTarget + } + lowSum += item.lowerBound + highSum += item.upperBound + targetSum += target + relativeItem := relativeAllocItem{ + target: target, + relativeLowerBound: item.lowerBound / target, + relativeUpperBound: item.upperBound / target, + } + ubRange.note(relativeItem.relativeUpperBound) + lbRange.note(relativeItem.relativeLowerBound) + relativeItems[idx] = relativeItem + } + if lbRange.max > 1 { + return nil, 0, fmt.Errorf("lbRange.max-1=%v, which is impossible because lbRange.max can not be greater than 1", lbRange.max-1) + } + if lowSum-requiredSumF > epsilon { + return nil, 0, fmt.Errorf("lower bounds sum to %v, which is higher than the required sum of %v", lowSum, requiredSum) + } + if requiredSumF-highSum > epsilon { + return nil, 0, fmt.Errorf("upper bounds sum to %v, which is lower than the required sum of %v", highSum, requiredSum) + } + ans := make([]float64, len(classes)) + if requiredSum == 0 { + return ans, 0, nil + } + if lowSum-requiredSumF > -epsilon { // no wiggle room, constrained from below + for idx, item := range classes { + ans[idx] = item.lowerBound + } + return ans, lbRange.min, nil + } + if requiredSumF-highSum > -epsilon { // no wiggle room, constrained from above + for idx, item := range classes { + ans[idx] = item.upperBound + } + return ans, ubRange.max, nil + } + // Now we know the solution is a unique fairProp in [lbRange.min, ubRange.max]. + // See if the solution does not run into any bounds. + fairProp := requiredSumF / targetSum + if lbRange.max <= fairProp && fairProp <= ubRange.min { // no bounds matter + for idx := range classes { + ans[idx] = relativeItems[idx].target * fairProp + } + return ans, fairProp, nil + } + // Sadly, some bounds matter. + // We find the solution by sorting the bounds and considering progressively + // higher values of fairProp, starting from lbRange.min. + rap := (&relativeAllocProblem{items: relativeItems}).initIndices() + sumSoFar := lowSum + fairProp = lbRange.min + var sensitiveTargetSum, deltaSensitiveTargetSum float64 + var numSensitiveClasses, deltaSensitiveClasses int + var nextIdx int + // `nextIdx` is the next `rap` index to consider. + // `sumSoFar` is what the allocs would sum to if the current + // value of `fairProp` solves the problem. + // If the current value of fairProp were the answer then + // `sumSoFar == requiredSum`. + // Otherwise the next increment in fairProp involves changing the allocations + // of `numSensitiveClasses` classes whose targets sum to `sensitiveTargetSum`; + // for the other classes, an upper or lower bound has applied and will continue to apply. + // The last increment of nextIdx calls for adding `deltaSensitiveClasses` + // to `numSensitiveClasses` and adding `deltaSensitiveTargetSum` to `sensitiveTargetSum`. + for sumSoFar < requiredSumF { + // There might be more than one bound that is equal to the current value + // of fairProp; find all of them because they will all be relevant to + // the next change in fairProp. + // Set nextBound to the next bound that is NOT equal to fairProp, + // and advance nextIdx to the index of that bound. + var nextBound float64 + for { + sensitiveTargetSum += deltaSensitiveTargetSum + numSensitiveClasses += deltaSensitiveClasses + if nextIdx >= rap.Len() { + return nil, 0, fmt.Errorf("impossible: ran out of bounds to consider in bound-constrained problem") + } + var itemIdx int + var lower bool + nextBound, itemIdx, lower = rap.decode(nextIdx) + if lower { + deltaSensitiveClasses = 1 + deltaSensitiveTargetSum = rap.items[itemIdx].target + } else { + deltaSensitiveClasses = -1 + deltaSensitiveTargetSum = -rap.items[itemIdx].target + } + nextIdx++ + if nextBound > fairProp { + break + } + } + // fairProp can increase to nextBound without passing any intermediate bounds. + if numSensitiveClasses == 0 { + // No classes are affected by the next range of fairProp; skip right past it + fairProp = nextBound + continue + } + // See whether fairProp can increase to the solution before passing the next bound. + deltaFairProp := (requiredSumF - sumSoFar) / sensitiveTargetSum + nextProp := fairProp + deltaFairProp + if nextProp <= nextBound { + fairProp = nextProp + break + } + // No, fairProp has to increase above nextBound + sumSoFar += (nextBound - fairProp) * sensitiveTargetSum + fairProp = nextBound + } + for idx, item := range classes { + ans[idx] = math.Max(item.lowerBound, math.Min(item.upperBound, fairProp*relativeItems[idx].target)) + } + return ans, fairProp, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/debug/dump.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/debug/dump.go new file mode 100644 index 0000000000..f2945b613f --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/debug/dump.go @@ -0,0 +1,64 @@ +/* +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 debug + +import ( + "time" + + "k8s.io/apiserver/pkg/endpoints/request" + flowcontrolrequest "k8s.io/apiserver/pkg/util/flowcontrol/request" +) + +// QueueSetDump is an instant dump of queue-set. +type QueueSetDump struct { + Queues []QueueDump + Waiting int + Executing int + SeatsInUse int + SeatsWaiting int + Dispatched int + Rejected int + Timedout int + Cancelled int +} + +// QueueDump is an instant dump of one queue in a queue-set. +type QueueDump struct { + QueueSum QueueSum + Requests []RequestDump + NextDispatchR string + ExecutingRequests int + SeatsInUse int +} + +type QueueSum struct { + InitialSeatsSum int + MaxSeatsSum int + TotalWorkSum string +} + +// RequestDump is an instant dump of one requests pending in the queue. +type RequestDump struct { + MatchedFlowSchema string + FlowDistinguisher string + ArriveTime time.Time + StartTime time.Time + WorkEstimate flowcontrolrequest.WorkEstimate + // request details + UserName string + RequestInfo request.RequestInfo +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/interface.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/interface.go new file mode 100644 index 0000000000..58f88b9924 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/interface.go @@ -0,0 +1,47 @@ +/* +Copyright 2021 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 eventclock + +import ( + "time" + + baseclock "k8s.io/utils/clock" +) + +// EventFunc does some work that needs to be done at or after the +// given time. +type EventFunc func(time.Time) + +// EventClock is an active clock abstraction for use in code that is +// testable with a fake clock that itself determines how time may be +// advanced. The timing paradigm is invoking EventFuncs rather than +// synchronizing through channels, so that the fake clock has a handle +// on when associated activity is done. +type Interface interface { + baseclock.PassiveClock + + // Sleep returns after the given duration (or more). + Sleep(d time.Duration) + + // EventAfterDuration invokes the given EventFunc after the given duration (or more), + // passing the time when the invocation was launched. + EventAfterDuration(f EventFunc, d time.Duration) + + // EventAfterTime invokes the given EventFunc at the given time or later, + // passing the time when the invocation was launched. + EventAfterTime(f EventFunc, t time.Time) +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/real.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/real.go new file mode 100644 index 0000000000..d567a0f45e --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/real.go @@ -0,0 +1,44 @@ +/* +Copyright 2021 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 eventclock + +import ( + "time" + + "k8s.io/utils/clock" +) + +// RealEventClock fires event on real world time +type Real struct { + clock.RealClock +} + +var _ Interface = Real{} + +// EventAfterDuration schedules an EventFunc +func (Real) EventAfterDuration(f EventFunc, d time.Duration) { + ch := time.After(d) + go func() { + t := <-ch + f(t) + }() +} + +// EventAfterTime schedules an EventFunc +func (r Real) EventAfterTime(f EventFunc, t time.Time) { + r.EventAfterDuration(f, time.Until(t)) +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/integrator.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/integrator.go new file mode 100644 index 0000000000..f421a6425b --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/integrator.go @@ -0,0 +1,191 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fairqueuing + +import ( + "math" + "sync" + "time" + + fcmetrics "k8s.io/apiserver/pkg/util/flowcontrol/metrics" + + "k8s.io/utils/clock" +) + +// Integrator computes the moments of some variable X over time as +// read from a particular clock. The integrals start when the +// Integrator is created, and ends at the latest operation on the +// Integrator. +type Integrator interface { + fcmetrics.Gauge + + GetResults() IntegratorResults + + // Return the results of integrating to now, and reset integration to start now + Reset() IntegratorResults +} + +// IntegratorResults holds statistical abstracts of the integration +type IntegratorResults struct { + Duration float64 //seconds + Average float64 //time-weighted + Deviation float64 //standard deviation: sqrt(avg((value-avg)^2)) + Min, Max float64 +} + +// Equal tests for semantic equality. +// This considers all NaN values to be equal to each other. +func (x *IntegratorResults) Equal(y *IntegratorResults) bool { + return x == y || x != nil && y != nil && x.Duration == y.Duration && x.Min == y.Min && x.Max == y.Max && (x.Average == y.Average || math.IsNaN(x.Average) && math.IsNaN(y.Average)) && (x.Deviation == y.Deviation || math.IsNaN(x.Deviation) && math.IsNaN(y.Deviation)) +} + +type integrator struct { + name string + clock clock.PassiveClock + sync.Mutex + lastTime time.Time + x float64 + moments Moments + min, max float64 +} + +// NewNamedIntegrator makes one that uses the given clock and name +func NewNamedIntegrator(clock clock.PassiveClock, name string) Integrator { + return &integrator{ + name: name, + clock: clock, + lastTime: clock.Now(), + } +} + +func (igr *integrator) Set(x float64) { + igr.Lock() + igr.setLocked(x) + igr.Unlock() +} + +func (igr *integrator) Add(deltaX float64) { + igr.Lock() + igr.setLocked(igr.x + deltaX) + igr.Unlock() +} + +func (igr *integrator) Inc() { + igr.Add(1) +} + +func (igr *integrator) Dec() { + igr.Add(-1) +} + +func (igr *integrator) SetToCurrentTime() { + igr.Set(float64(time.Now().UnixNano())) +} + +func (igr *integrator) setLocked(x float64) { + igr.updateLocked() + igr.x = x + if x < igr.min { + igr.min = x + } + if x > igr.max { + igr.max = x + } +} + +func (igr *integrator) updateLocked() { + now := igr.clock.Now() + dt := now.Sub(igr.lastTime).Seconds() + igr.lastTime = now + igr.moments = igr.moments.Add(ConstantMoments(dt, igr.x)) +} + +func (igr *integrator) GetResults() IntegratorResults { + igr.Lock() + defer igr.Unlock() + return igr.getResultsLocked() +} + +func (igr *integrator) Reset() IntegratorResults { + igr.Lock() + defer igr.Unlock() + results := igr.getResultsLocked() + igr.moments = Moments{} + igr.min = igr.x + igr.max = igr.x + return results +} + +func (igr *integrator) getResultsLocked() (results IntegratorResults) { + igr.updateLocked() + results.Min, results.Max = igr.min, igr.max + results.Duration = igr.moments.ElapsedSeconds + results.Average, results.Deviation = igr.moments.AvgAndStdDev() + return +} + +// Moments are the integrals of the 0, 1, and 2 powers of some +// variable X over some range of time. +type Moments struct { + ElapsedSeconds float64 // integral of dt + IntegralX float64 // integral of x dt + IntegralXX float64 // integral of x*x dt +} + +// ConstantMoments is for a constant X +func ConstantMoments(dt, x float64) Moments { + return Moments{ + ElapsedSeconds: dt, + IntegralX: x * dt, + IntegralXX: x * x * dt, + } +} + +// Add combines over two ranges of time +func (igr Moments) Add(ogr Moments) Moments { + return Moments{ + ElapsedSeconds: igr.ElapsedSeconds + ogr.ElapsedSeconds, + IntegralX: igr.IntegralX + ogr.IntegralX, + IntegralXX: igr.IntegralXX + ogr.IntegralXX, + } +} + +// Sub finds the difference between a range of time and a subrange +func (igr Moments) Sub(ogr Moments) Moments { + return Moments{ + ElapsedSeconds: igr.ElapsedSeconds - ogr.ElapsedSeconds, + IntegralX: igr.IntegralX - ogr.IntegralX, + IntegralXX: igr.IntegralXX - ogr.IntegralXX, + } +} + +// AvgAndStdDev returns the average and standard devation +func (igr Moments) AvgAndStdDev() (float64, float64) { + if igr.ElapsedSeconds <= 0 { + return math.NaN(), math.NaN() + } + avg := igr.IntegralX / igr.ElapsedSeconds + // standard deviation is sqrt( average( (x - xbar)^2 ) ) + // = sqrt( Integral( x^2 + xbar^2 -2*x*xbar dt ) / Duration ) + // = sqrt( ( Integral( x^2 dt ) + Duration * xbar^2 - 2*xbar*Integral(x dt) ) / Duration) + // = sqrt( Integral(x^2 dt)/Duration - xbar^2 ) + variance := igr.IntegralXX/igr.ElapsedSeconds - avg*avg + if variance >= 0 { + return avg, math.Sqrt(variance) + } + return avg, math.NaN() +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/interface.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/interface.go new file mode 100644 index 0000000000..5522bb4554 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/interface.go @@ -0,0 +1,136 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fairqueuing + +import ( + "context" + "time" + + "k8s.io/apiserver/pkg/util/flowcontrol/debug" + "k8s.io/apiserver/pkg/util/flowcontrol/metrics" + "k8s.io/apiserver/pkg/util/flowcontrol/request" +) + +// QueueSetFactory is used to create QueueSet objects. Creation, like +// config update, is done in two phases: the first phase consumes the +// QueuingConfig and the second consumes the DispatchingConfig. They +// are separated so that errors from the first phase can be found +// before committing to a concurrency allotment for the second. +type QueueSetFactory interface { + // BeginConstruction does the first phase of creating a QueueSet. + // The RatioedGaugePair observes number of requests, + // execution covering just the regular phase. + // The RatioedGauge observes number of seats occupied through all phases of execution. + // The Gauge observes the seat demand (executing + queued seats). + BeginConstruction(QueuingConfig, metrics.RatioedGaugePair, metrics.RatioedGauge, metrics.Gauge) (QueueSetCompleter, error) +} + +// QueueSetCompleter finishes the two-step process of creating or +// reconfiguring a QueueSet +type QueueSetCompleter interface { + // Complete returns a QueueSet configured by the given + // dispatching configuration. + Complete(DispatchingConfig) QueueSet +} + +// QueueSet is the abstraction for the queuing and dispatching +// functionality of one non-exempt priority level. It covers the +// functionality described in the "Assignment to a Queue", "Queuing", +// and "Dispatching" sections of +// https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/1040-priority-and-fairness/README.md +// . Some day we may have connections between priority levels, but +// today is not that day. +type QueueSet interface { + // BeginConfigChange starts the two-step process of updating the + // configuration. No change is made until Complete is called. If + // `C := X.BeginConstruction(q)` then `C.Complete(d)` returns the + // same value `X`. If the QueuingConfig's DesiredNumQueues field + // is zero then the other queuing-specific config parameters are + // not changed, so that the queues continue draining as before. + // In any case, reconfiguration does not discard any queue unless + // and until it is undesired and empty. + BeginConfigChange(QueuingConfig) (QueueSetCompleter, error) + + // IsIdle returns a bool indicating whether the QueueSet was idle + // at the moment of the return. Idle means the QueueSet has zero + // requests queued and zero executing. This bit can change only + // (1) during a call to StartRequest and (2) during a call to + // Request::Finish. In the latter case idleness can only change + // from false to true. + IsIdle() bool + + // StartRequest begins the process of handling a request. If the + // request gets queued and the number of queues is greater than 1 + // then StartRequest uses the given hashValue as the source of + // entropy as it shuffle-shards the request into a queue. The + // descr1 and descr2 values play no role in the logic but appear + // in log messages. This method always returns quickly (without + // waiting for the request to be dequeued). If this method + // returns a nil Request value then caller should reject the + // request and the returned bool indicates whether the QueueSet + // was idle at the moment of the return. Otherwise idle==false + // and the client must call the Finish method of the Request + // exactly once. + StartRequest(ctx context.Context, width *request.WorkEstimate, hashValue uint64, flowDistinguisher, fsName string, descr1, descr2 interface{}, queueNoteFn QueueNoteFn) (req Request, idle bool) + + // Dump saves and returns the instant internal state of the queue-set. + // Note that dumping process will stop the queue-set from proceeding + // any requests. + // For debugging only. + Dump(includeRequestDetails bool) debug.QueueSetDump +} + +// QueueNoteFn is called when a request enters and leaves a queue +type QueueNoteFn func(inQueue bool) + +// Request represents the remainder of the handling of one request +type Request interface { + // Finish determines whether to execute or reject the request and + // invokes `execute` if the decision is to execute the request. + // The returned `idle bool` value indicates whether the QueueSet + // was idle when the value was calculated, but might no longer be + // accurate by the time the client examines that value. + Finish(execute func()) (idle bool) +} + +// QueuingConfig defines the configuration of the queuing aspect of a QueueSet. +type QueuingConfig struct { + // Name is used to identify a queue set, allowing for descriptive information about its intended use + Name string + + // DesiredNumQueues is the number of queues that the API says + // should exist now. This may be zero, in which case + // QueueLengthLimit, HandSize, and RequestWaitLimit are ignored. + DesiredNumQueues int + + // QueueLengthLimit is the maximum number of requests that may be waiting in a given queue at a time + QueueLengthLimit int + + // HandSize is a parameter of shuffle sharding. Upon arrival of a request, a queue is chosen by randomly + // dealing a "hand" of this many queues and then picking one of minimum length. + HandSize int + + // RequestWaitLimit is the maximum amount of time that a request may wait in a queue. + // If, by the end of that time, the request has not been dispatched then it is rejected. + RequestWaitLimit time.Duration +} + +// DispatchingConfig defines the configuration of the dispatching aspect of a QueueSet. +type DispatchingConfig struct { + // ConcurrencyLimit is the maximum number of requests of this QueueSet that may be executing at a time + ConcurrencyLimit int +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/interface.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/interface.go new file mode 100644 index 0000000000..b2e3adbdcb --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/interface.go @@ -0,0 +1,34 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package promise + +// WriteOnce represents a variable that is initially not set and can +// be set once and is readable. This is the common meaning for +// "promise". +type WriteOnce interface { + // Get reads the current value of this variable. If this + // variable is not set yet then this call blocks until this + // variable gets a value. + Get() interface{} + + // Set normally writes a value into this variable, unblocks every + // goroutine waiting for this variable to have a value, and + // returns true. In the unhappy case that this variable is + // already set, this method returns false without modifying the + // variable's value. + Set(interface{}) bool +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/promise.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/promise.go new file mode 100644 index 0000000000..d3bda40aaa --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/promise.go @@ -0,0 +1,70 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package promise + +import ( + "sync" +) + +// promise implements the WriteOnce interface. +type promise struct { + doneCh <-chan struct{} + doneVal interface{} + setCh chan struct{} + onceler sync.Once + value interface{} +} + +var _ WriteOnce = &promise{} + +// NewWriteOnce makes a new thread-safe WriteOnce. +// +// If `initial` is non-nil then that value is Set at creation time. +// +// If a `Get` is waiting soon after `doneCh` becomes selectable (which +// never happens for the nil channel) then `Set(doneVal)` effectively +// happens at that time. +func NewWriteOnce(initial interface{}, doneCh <-chan struct{}, doneVal interface{}) WriteOnce { + p := &promise{ + doneCh: doneCh, + doneVal: doneVal, + setCh: make(chan struct{}), + } + if initial != nil { + p.Set(initial) + } + return p +} + +func (p *promise) Get() interface{} { + select { + case <-p.setCh: + case <-p.doneCh: + p.Set(p.doneVal) + } + return p.value +} + +func (p *promise) Set(value interface{}) bool { + var ans bool + p.onceler.Do(func() { + p.value = value + close(p.setCh) + ans = true + }) + return ans +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/doc.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/doc.go new file mode 100644 index 0000000000..fc30ebfd5b --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/doc.go @@ -0,0 +1,119 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package queueset implements a technique called "fair queuing for +// server requests". One QueueSet is a set of queues operating +// according to this technique. +// +// Fair queuing for server requests is inspired by the fair queuing +// technique from the world of networking. You can find a good paper +// on that at https://dl.acm.org/citation.cfm?doid=75247.75248 or +// http://people.csail.mit.edu/imcgraw/links/research/pubs/networks/WFQ.pdf +// and there is an implementation outline in the Wikipedia article at +// https://en.wikipedia.org/wiki/Fair_queuing . +// +// Fair queuing for server requests differs from traditional fair +// queuing in three ways: (1) we are dispatching application layer +// requests to a server rather than transmitting packets on a network +// link, (2) multiple requests can be executing at once, and (3) the +// service time (execution duration) is not known until the execution +// completes. +// +// The first two differences can easily be handled by straightforward +// adaptation of the concept called "R(t)" in the original paper and +// "virtual time" in the implementation outline. In that +// implementation outline, the notation now() is used to mean reading +// the virtual clock. In the original paper’s terms, "R(t)" is the +// number of "rounds" that have been completed at real time t --- +// where a round consists of virtually transmitting one bit from every +// non-empty queue in the router (regardless of which queue holds the +// packet that is really being transmitted at the moment); in this +// conception, a packet is considered to be "in" its queue until the +// packet’s transmission is finished. For our problem, we can define a +// round to be giving one nanosecond of CPU to every non-empty queue +// in the apiserver (where emptiness is judged based on both queued +// and executing requests from that queue), and define R(t) = (server +// start time) + (1 ns) * (number of rounds since server start). Let +// us write NEQ(t) for that number of non-empty queues in the +// apiserver at time t. Let us also write C for the concurrency +// limit. In the original paper, the partial derivative of R(t) with +// respect to t is +// +// 1 / NEQ(t) . +// +// To generalize from transmitting one packet at a time to executing C +// requests at a time, that derivative becomes +// +// C / NEQ(t) . +// +// However, sometimes there are fewer than C requests available to +// execute. For a given queue "q", let us also write "reqs(q, t)" for +// the number of requests of that queue that are executing at that +// time. The total number of requests executing is sum[over q] +// reqs(q, t) and if that is less than C then virtual time is not +// advancing as fast as it would if all C seats were occupied; in this +// case the numerator of the quotient in that derivative should be +// adjusted proportionally. Putting it all together for fair queing +// for server requests: at a particular time t, the partial derivative +// of R(t) with respect to t is +// +// min( C, sum[over q] reqs(q, t) ) / NEQ(t) . +// +// In terms of the implementation outline, this is the rate at which +// virtual time is advancing at time t (in virtual nanoseconds per +// real nanosecond). Where the networking implementation outline adds +// packet size to a virtual time, in our version this corresponds to +// adding a service time (i.e., duration) to virtual time. +// +// The third difference is handled by modifying the algorithm to +// dispatch based on an initial guess at the request’s service time +// (duration) and then make the corresponding adjustments once the +// request’s actual service time is known. This is similar, although +// not exactly isomorphic, to the original paper’s adjustment by +// `$\delta$` for the sake of promptness. +// +// For implementation simplicity (see below), let us use the same +// initial service time guess for every request; call that duration +// G. A good choice might be the service time limit (1 +// minute). Different guesses will give slightly different dynamics, +// but any positive number can be used for G without ruining the +// long-term behavior. +// +// As in ordinary fair queuing, there is a bound on divergence from +// the ideal. In plain fair queuing the bound is one packet; in our +// version it is C requests. +// +// To support efficiently making the necessary adjustments once a +// request’s actual service time is known, the virtual finish time of +// a request and the last virtual finish time of a queue are not +// represented directly but instead computed from queue length, +// request position in the queue, and an alternate state variable that +// holds the queue’s virtual start time. While the queue is empty and +// has no requests executing: the value of its virtual start time +// variable is ignored and its last virtual finish time is considered +// to be in the virtual past. When a request arrives to an empty queue +// with no requests executing, the queue’s virtual start time is set +// to the current virtual time. The virtual finish time of request +// number J in the queue (counting from J=1 for the head) is J * G + +// (queue's virtual start time). While the queue is non-empty: the +// last virtual finish time of the queue is the virtual finish time of +// the last request in the queue. While the queue is empty and has a +// request executing: the last virtual finish time is the queue’s +// virtual start time. When a request is dequeued for service the +// queue’s virtual start time is advanced by G. When a request +// finishes being served, and the actual service time was S, the +// queue’s virtual start time is decremented by G - S. +package queueset diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/fifo_list.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/fifo_list.go new file mode 100644 index 0000000000..eb56e1e946 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/fifo_list.go @@ -0,0 +1,156 @@ +/* +Copyright 2021 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 queueset + +import ( + "container/list" +) + +// removeFromFIFOFunc removes a designated element from the list +// if that element is in the list. +// The complexity of the runtime cost is O(1). +// The returned value is the element removed, if indeed one was removed, +// otherwise `nil`. +type removeFromFIFOFunc func() *request + +// walkFunc is called for each request in the list in the +// oldest -> newest order. +// ok: if walkFunc returns false then the iteration stops immediately. +// walkFunc may remove the given request from the fifo, +// but may not mutate the fifo in any othe way. +type walkFunc func(*request) (ok bool) + +// Internal interface to abstract out the implementation details +// of the underlying list used to maintain the requests. +// +// Note that a fifo, including the removeFromFIFOFuncs returned from Enqueue, +// is not safe for concurrent use by multiple goroutines. +type fifo interface { + // Enqueue enqueues the specified request into the list and + // returns a removeFromFIFOFunc function that can be used to remove the + // request from the list + Enqueue(*request) removeFromFIFOFunc + + // Dequeue pulls out the oldest request from the list. + Dequeue() (*request, bool) + + // Peek returns the oldest request without removing it. + Peek() (*request, bool) + + // Length returns the number of requests in the list. + Length() int + + // QueueSum returns the sum of initial seats, final seats, and + // additional latency aggregated from all requests in this queue. + QueueSum() queueSum + + // Walk iterates through the list in order of oldest -> newest + // and executes the specified walkFunc for each request in that order. + // + // if the specified walkFunc returns false the Walk function + // stops the walk an returns immediately. + Walk(walkFunc) +} + +// the FIFO list implementation is not safe for concurrent use by multiple +// goroutines. +type requestFIFO struct { + *list.List + + sum queueSum +} + +func newRequestFIFO() fifo { + return &requestFIFO{ + List: list.New(), + } +} + +func (l *requestFIFO) Length() int { + return l.Len() +} + +func (l *requestFIFO) QueueSum() queueSum { + return l.sum +} + +func (l *requestFIFO) Enqueue(req *request) removeFromFIFOFunc { + e := l.PushBack(req) + addToQueueSum(&l.sum, req) + + return func() *request { + if e.Value == nil { + return nil + } + l.Remove(e) + e.Value = nil + deductFromQueueSum(&l.sum, req) + return req + } +} + +func (l *requestFIFO) Dequeue() (*request, bool) { + return l.getFirst(true) +} + +func (l *requestFIFO) Peek() (*request, bool) { + return l.getFirst(false) +} + +func (l *requestFIFO) getFirst(remove bool) (*request, bool) { + e := l.Front() + if e == nil { + return nil, false + } + + if remove { + defer func() { + l.Remove(e) + e.Value = nil + }() + } + + request, ok := e.Value.(*request) + if remove && ok { + deductFromQueueSum(&l.sum, request) + } + return request, ok +} + +func (l *requestFIFO) Walk(f walkFunc) { + var next *list.Element + for current := l.Front(); current != nil; current = next { + next = current.Next() // f is allowed to remove current + if r, ok := current.Value.(*request); ok { + if !f(r) { + return + } + } + } +} + +func addToQueueSum(sum *queueSum, req *request) { + sum.InitialSeatsSum += req.InitialSeats() + sum.MaxSeatsSum += req.MaxSeats() + sum.TotalWorkSum += req.totalWork() +} + +func deductFromQueueSum(sum *queueSum, req *request) { + sum.InitialSeatsSum -= req.InitialSeats() + sum.MaxSeatsSum -= req.MaxSeats() + sum.TotalWorkSum -= req.totalWork() +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go new file mode 100644 index 0000000000..11c15ccb72 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go @@ -0,0 +1,1086 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package queueset + +import ( + "context" + "errors" + "fmt" + "math" + "sync" + "time" + + "k8s.io/apiserver/pkg/util/flowcontrol/debug" + fq "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing" + "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock" + "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise" + "k8s.io/apiserver/pkg/util/flowcontrol/metrics" + fqrequest "k8s.io/apiserver/pkg/util/flowcontrol/request" + "k8s.io/apiserver/pkg/util/shufflesharding" + "k8s.io/klog/v2" + + // The following hack is needed to work around a tooling deficiency. + // Packages imported only for test code are not included in vendor. + // See https://kubernetes.slack.com/archives/C0EG7JC6T/p1626985671458800?thread_ts=1626983387.450800&cid=C0EG7JC6T + _ "k8s.io/utils/clock/testing" +) + +const nsTimeFmt = "2006-01-02 15:04:05.000000000" + +// queueSetFactory implements the QueueSetFactory interface +// queueSetFactory makes QueueSet objects. +type queueSetFactory struct { + clock eventclock.Interface + promiseFactoryFactory promiseFactoryFactory +} + +// promiseFactory returns a WriteOnce +// - whose Set method is invoked with the queueSet locked, and +// - whose Get method is invoked with the queueSet not locked. +// The parameters are the same as for `promise.NewWriteOnce`. +type promiseFactory func(initial interface{}, doneCh <-chan struct{}, doneVal interface{}) promise.WriteOnce + +// promiseFactoryFactory returns the promiseFactory to use for the given queueSet +type promiseFactoryFactory func(*queueSet) promiseFactory + +// `*queueSetCompleter` implements QueueSetCompleter. Exactly one of +// the fields `factory` and `theSet` is non-nil. +type queueSetCompleter struct { + factory *queueSetFactory + reqsGaugePair metrics.RatioedGaugePair + execSeatsGauge metrics.RatioedGauge + seatDemandIntegrator metrics.Gauge + theSet *queueSet + qCfg fq.QueuingConfig + dealer *shufflesharding.Dealer +} + +// queueSet implements the Fair Queuing for Server Requests technique +// described in this package's doc, and a pointer to one implements +// the QueueSet interface. The fields listed before the lock +// should not be changed; the fields listed after the +// lock must be accessed only while holding the lock. +// +// The methods of this type follow the naming convention that the +// suffix "Locked" means the caller must hold the lock; for a method +// whose name does not end in "Locked" either acquires the lock or +// does not care about locking. +// +// The methods of this type also follow the convention that the suffix +// "ToBoundLocked" means that the caller may have to follow up with a +// call to `boundNextDispatchLocked`. This is so for a method that +// changes what request is oldest in a queue, because that change means +// that the anti-windup hack in boundNextDispatchLocked needs to be +// applied wrt the revised oldest request in the queue. +type queueSet struct { + clock eventclock.Interface + estimatedServiceDuration time.Duration + + reqsGaugePair metrics.RatioedGaugePair // .RequestsExecuting covers regular phase only + + execSeatsGauge metrics.RatioedGauge // for all phases of execution + + seatDemandIntegrator metrics.Gauge + + promiseFactory promiseFactory + + lock sync.Mutex + + // qCfg holds the current queuing configuration. Its + // DesiredNumQueues may be less than the current number of queues. + // If its DesiredNumQueues is zero then its other queuing + // parameters retain the settings they had when DesiredNumQueues + // was last non-zero (if ever). + qCfg fq.QueuingConfig + + // the current dispatching configuration. + dCfg fq.DispatchingConfig + + // If `qCfg.DesiredNumQueues` is non-zero then dealer is not nil + // and is good for `qCfg`. + dealer *shufflesharding.Dealer + + // queues may be longer than the desired number, while the excess + // queues are still draining. + queues []*queue + + // currentR is the amount of seat-seconds allocated per queue since process startup. + // This is our generalization of the progress meter named R in the original fair queuing work. + currentR fqrequest.SeatSeconds + + // lastRealTime is what `clock.Now()` yielded when `virtualTime` was last updated + lastRealTime time.Time + + // robinIndex is the index of the last queue dispatched + robinIndex int + + // totRequestsWaiting is the sum, over all the queues, of the + // number of requests waiting in that queue + totRequestsWaiting int + + // totRequestsExecuting is the total number of requests of this + // queueSet that are currently executing. That is the same as the + // sum, over all the queues, of the number of requests executing + // from that queue. + totRequestsExecuting int + + // totSeatsInUse is the number of total "seats" in use by all the + // request(s) that are currently executing in this queueset. + totSeatsInUse int + + // totSeatsWaiting is the sum, over all the waiting requests, of their + // max width. + totSeatsWaiting int + + // enqueues is the number of requests that have ever been enqueued + enqueues int + + // totRequestsDispatched is the total number of requests of this + // queueSet that have been processed. + totRequestsDispatched int + + // totRequestsRejected is the total number of requests of this + // queueSet that have been rejected. + totRequestsRejected int + + // totRequestsTimedout is the total number of requests of this + // queueSet that have been timeouted. + totRequestsTimedout int + + // totRequestsCancelled is the total number of requests of this + // queueSet that have been cancelled. + totRequestsCancelled int +} + +// NewQueueSetFactory creates a new QueueSetFactory object +func NewQueueSetFactory(c eventclock.Interface) fq.QueueSetFactory { + return newTestableQueueSetFactory(c, ordinaryPromiseFactoryFactory) +} + +// newTestableQueueSetFactory creates a new QueueSetFactory object with the given promiseFactoryFactory +func newTestableQueueSetFactory(c eventclock.Interface, promiseFactoryFactory promiseFactoryFactory) fq.QueueSetFactory { + return &queueSetFactory{ + clock: c, + promiseFactoryFactory: promiseFactoryFactory, + } +} + +func (qsf *queueSetFactory) BeginConstruction(qCfg fq.QueuingConfig, reqsGaugePair metrics.RatioedGaugePair, execSeatsGauge metrics.RatioedGauge, seatDemandIntegrator metrics.Gauge) (fq.QueueSetCompleter, error) { + dealer, err := checkConfig(qCfg) + if err != nil { + return nil, err + } + return &queueSetCompleter{ + factory: qsf, + reqsGaugePair: reqsGaugePair, + execSeatsGauge: execSeatsGauge, + seatDemandIntegrator: seatDemandIntegrator, + qCfg: qCfg, + dealer: dealer}, nil +} + +// checkConfig returns a non-nil Dealer if the config is valid and +// calls for one, and returns a non-nil error if the given config is +// invalid. +func checkConfig(qCfg fq.QueuingConfig) (*shufflesharding.Dealer, error) { + if qCfg.DesiredNumQueues == 0 { + return nil, nil + } + dealer, err := shufflesharding.NewDealer(qCfg.DesiredNumQueues, qCfg.HandSize) + if err != nil { + err = fmt.Errorf("the QueueSetConfig implies an invalid shuffle sharding config (DesiredNumQueues is deckSize): %w", err) + } + return dealer, err +} + +func (qsc *queueSetCompleter) Complete(dCfg fq.DispatchingConfig) fq.QueueSet { + qs := qsc.theSet + if qs == nil { + qs = &queueSet{ + clock: qsc.factory.clock, + estimatedServiceDuration: 3 * time.Millisecond, + reqsGaugePair: qsc.reqsGaugePair, + execSeatsGauge: qsc.execSeatsGauge, + seatDemandIntegrator: qsc.seatDemandIntegrator, + qCfg: qsc.qCfg, + currentR: 0, + lastRealTime: qsc.factory.clock.Now(), + } + qs.promiseFactory = qsc.factory.promiseFactoryFactory(qs) + } + qs.setConfiguration(context.Background(), qsc.qCfg, qsc.dealer, dCfg) + return qs +} + +// createQueues is a helper method for initializing an array of n queues +func createQueues(n, baseIndex int) []*queue { + fqqueues := make([]*queue, n) + for i := 0; i < n; i++ { + fqqueues[i] = &queue{index: baseIndex + i, requests: newRequestFIFO()} + } + return fqqueues +} + +func (qs *queueSet) BeginConfigChange(qCfg fq.QueuingConfig) (fq.QueueSetCompleter, error) { + dealer, err := checkConfig(qCfg) + if err != nil { + return nil, err + } + return &queueSetCompleter{ + theSet: qs, + qCfg: qCfg, + dealer: dealer}, nil +} + +// setConfiguration is used to set the configuration for a queueSet. +// Update handling for when fields are updated is handled here as well - +// eg: if DesiredNum is increased, setConfiguration reconciles by +// adding more queues. +func (qs *queueSet) setConfiguration(ctx context.Context, qCfg fq.QueuingConfig, dealer *shufflesharding.Dealer, dCfg fq.DispatchingConfig) { + qs.lockAndSyncTime(ctx) + defer qs.lock.Unlock() + + if qCfg.DesiredNumQueues > 0 { + // Adding queues is the only thing that requires immediate action + // Removing queues is handled by attrition, removing a queue when + // it goes empty and there are too many. + numQueues := len(qs.queues) + if qCfg.DesiredNumQueues > numQueues { + qs.queues = append(qs.queues, + createQueues(qCfg.DesiredNumQueues-numQueues, len(qs.queues))...) + } + } else { + qCfg.QueueLengthLimit = qs.qCfg.QueueLengthLimit + qCfg.HandSize = qs.qCfg.HandSize + qCfg.RequestWaitLimit = qs.qCfg.RequestWaitLimit + } + + qs.qCfg = qCfg + qs.dCfg = dCfg + qs.dealer = dealer + qll := qCfg.QueueLengthLimit + if qll < 1 { + qll = 1 + } + if qCfg.DesiredNumQueues > 0 { + qll *= qCfg.DesiredNumQueues + } + qs.reqsGaugePair.RequestsWaiting.SetDenominator(float64(qll)) + qs.reqsGaugePair.RequestsExecuting.SetDenominator(float64(dCfg.ConcurrencyLimit)) + qs.execSeatsGauge.SetDenominator(float64(dCfg.ConcurrencyLimit)) + + qs.dispatchAsMuchAsPossibleLocked() +} + +// A decision about a request +type requestDecision int + +// Values passed through a request's decision +const ( + // Serve this one + decisionExecute requestDecision = iota + + // Reject this one due to APF queuing considerations + decisionReject + + // This one's context timed out / was canceled + decisionCancel +) + +// StartRequest begins the process of handling a request. We take the +// approach of updating the metrics about total requests queued and +// executing at each point where there is a change in that quantity, +// because the metrics --- and only the metrics --- track that +// quantity per FlowSchema. +// The queueSet's promiseFactory is invoked once if the returned Request is non-nil, +// not invoked if the Request is nil. +func (qs *queueSet) StartRequest(ctx context.Context, workEstimate *fqrequest.WorkEstimate, hashValue uint64, flowDistinguisher, fsName string, descr1, descr2 interface{}, queueNoteFn fq.QueueNoteFn) (fq.Request, bool) { + qs.lockAndSyncTime(ctx) + defer qs.lock.Unlock() + var req *request + + // ======================================================================== + // Step 0: + // Apply only concurrency limit, if zero queues desired + if qs.qCfg.DesiredNumQueues < 1 { + if !qs.canAccommodateSeatsLocked(workEstimate.MaxSeats()) { + klog.V(5).Infof("QS(%s): rejecting request %q %#+v %#+v because %d seats are asked for, %d seats are in use (%d are executing) and the limit is %d", + qs.qCfg.Name, fsName, descr1, descr2, workEstimate, qs.totSeatsInUse, qs.totRequestsExecuting, qs.dCfg.ConcurrencyLimit) + qs.totRequestsRejected++ + metrics.AddReject(ctx, qs.qCfg.Name, fsName, "concurrency-limit") + return nil, qs.isIdleLocked() + } + req = qs.dispatchSansQueueLocked(ctx, workEstimate, flowDistinguisher, fsName, descr1, descr2) + return req, false + } + + // ======================================================================== + // Step 1: + // 1) Start with shuffle sharding, to pick a queue. + // 2) Reject old requests that have been waiting too long + // 3) Reject current request if there is not enough concurrency shares and + // we are at max queue length + // 4) If not rejected, create a request and enqueue + req = qs.timeoutOldRequestsAndRejectOrEnqueueLocked(ctx, workEstimate, hashValue, flowDistinguisher, fsName, descr1, descr2, queueNoteFn) + // req == nil means that the request was rejected - no remaining + // concurrency shares and at max queue length already + if req == nil { + klog.V(5).Infof("QS(%s): rejecting request %q %#+v %#+v due to queue full", qs.qCfg.Name, fsName, descr1, descr2) + qs.totRequestsRejected++ + metrics.AddReject(ctx, qs.qCfg.Name, fsName, "queue-full") + return nil, qs.isIdleLocked() + } + + // ======================================================================== + // Step 2: + // The next step is to invoke the method that dequeues as much + // as possible. + // This method runs a loop, as long as there are non-empty + // queues and the number currently executing is less than the + // assured concurrency value. The body of the loop uses the + // fair queuing technique to pick a queue and dispatch a + // request from that queue. + qs.dispatchAsMuchAsPossibleLocked() + + return req, false +} + +// ordinaryPromiseFactoryFactory is the promiseFactoryFactory that +// a queueSetFactory would ordinarily use. +// Test code might use something different. +func ordinaryPromiseFactoryFactory(qs *queueSet) promiseFactory { + return promise.NewWriteOnce +} + +// MaxSeats returns the maximum number of seats this request requires, it is +// the maxumum of the two - WorkEstimate.InitialSeats, WorkEstimate.FinalSeats. +func (req *request) MaxSeats() int { + return req.workEstimate.MaxSeats() +} + +func (req *request) InitialSeats() int { + return int(req.workEstimate.InitialSeats) +} + +func (req *request) NoteQueued(inQueue bool) { + if req.queueNoteFn != nil { + req.queueNoteFn(inQueue) + } +} + +func (req *request) Finish(execFn func()) bool { + exec, idle := req.wait() + if !exec { + return idle + } + func() { + defer func() { + idle = req.qs.finishRequestAndDispatchAsMuchAsPossible(req) + }() + + execFn() + }() + + return idle +} + +func (req *request) wait() (bool, bool) { + qs := req.qs + + // ======================================================================== + // Step 3: + // The final step is to wait on a decision from + // somewhere and then act on it. + decisionAny := req.decision.Get() + qs.lockAndSyncTime(req.ctx) + defer qs.lock.Unlock() + if req.waitStarted { + // This can not happen, because the client is forbidden to + // call Wait twice on the same request + klog.Errorf("Duplicate call to the Wait method! Immediately returning execute=false. QueueSet=%s, startTime=%s, descr1=%#+v, descr2=%#+v", req.qs.qCfg.Name, req.startTime, req.descr1, req.descr2) + return false, qs.isIdleLocked() + } + req.waitStarted = true + switch decisionAny { + case decisionReject: + klog.V(5).Infof("QS(%s): request %#+v %#+v timed out after being enqueued\n", qs.qCfg.Name, req.descr1, req.descr2) + qs.totRequestsRejected++ + qs.totRequestsTimedout++ + metrics.AddReject(req.ctx, qs.qCfg.Name, req.fsName, "time-out") + return false, qs.isIdleLocked() + case decisionCancel: + case decisionExecute: + klog.V(5).Infof("QS(%s): Dispatching request %#+v %#+v from its queue", qs.qCfg.Name, req.descr1, req.descr2) + return true, false + default: + // This can not happen, all possible values are handled above + klog.Errorf("QS(%s): Impossible decision (type %T, value %#+v) for request %#+v %#+v! Treating as cancel", qs.qCfg.Name, decisionAny, decisionAny, req.descr1, req.descr2) + } + // TODO(aaron-prindle) add metrics for this case + klog.V(5).Infof("QS(%s): Ejecting request %#+v %#+v from its queue", qs.qCfg.Name, req.descr1, req.descr2) + // remove the request from the queue as it has timed out + queue := req.queue + if req.removeFromQueueLocked() != nil { + defer qs.boundNextDispatchLocked(queue) + qs.totRequestsWaiting-- + qs.totSeatsWaiting -= req.MaxSeats() + qs.totRequestsRejected++ + qs.totRequestsCancelled++ + metrics.AddReject(req.ctx, qs.qCfg.Name, req.fsName, "cancelled") + metrics.AddRequestsInQueues(req.ctx, qs.qCfg.Name, req.fsName, -1) + req.NoteQueued(false) + qs.reqsGaugePair.RequestsWaiting.Add(-1) + qs.seatDemandIntegrator.Set(float64(qs.totSeatsInUse + qs.totSeatsWaiting)) + } + return false, qs.isIdleLocked() +} + +func (qs *queueSet) IsIdle() bool { + qs.lock.Lock() + defer qs.lock.Unlock() + return qs.isIdleLocked() +} + +func (qs *queueSet) isIdleLocked() bool { + return qs.totRequestsWaiting == 0 && qs.totRequestsExecuting == 0 +} + +// lockAndSyncTime acquires the lock and updates the virtual time. +// Doing them together avoids the mistake of modifying some queue state +// before calling syncTimeLocked. +func (qs *queueSet) lockAndSyncTime(ctx context.Context) { + qs.lock.Lock() + qs.syncTimeLocked(ctx) +} + +// syncTimeLocked updates the virtual time based on the assumption +// that the current state of the queues has been in effect since +// `qs.lastRealTime`. Thus, it should be invoked after acquiring the +// lock and before modifying the state of any queue. +func (qs *queueSet) syncTimeLocked(ctx context.Context) { + realNow := qs.clock.Now() + timeSinceLast := realNow.Sub(qs.lastRealTime) + qs.lastRealTime = realNow + prevR := qs.currentR + incrR := fqrequest.SeatsTimesDuration(qs.getVirtualTimeRatioLocked(), timeSinceLast) + qs.currentR = prevR + incrR + switch { + case prevR > qs.currentR: + klog.ErrorS(errors.New("queueset::currentR overflow"), "Overflow", "QS", qs.qCfg.Name, "when", realNow.Format(nsTimeFmt), "prevR", prevR, "incrR", incrR, "currentR", qs.currentR) + case qs.currentR >= highR: + qs.advanceEpoch(ctx, realNow, incrR) + } + metrics.SetCurrentR(qs.qCfg.Name, qs.currentR.ToFloat()) +} + +// rDecrement is the amount by which the progress meter R is wound backwards +// when needed to avoid overflow. +const rDecrement = fqrequest.MaxSeatSeconds / 2 + +// highR is the threshold that triggers advance of the epoch. +// That is, decrementing the global progress meter R by rDecrement. +const highR = rDecrement + rDecrement/2 + +// advanceEpoch subtracts rDecrement from the global progress meter R +// and all the readings that have been taked from that meter. +// The now and incrR parameters are only used to add info to the log messages. +func (qs *queueSet) advanceEpoch(ctx context.Context, now time.Time, incrR fqrequest.SeatSeconds) { + oldR := qs.currentR + qs.currentR -= rDecrement + klog.InfoS("Advancing epoch", "QS", qs.qCfg.Name, "when", now.Format(nsTimeFmt), "oldR", oldR, "newR", qs.currentR, "incrR", incrR) + success := true + for qIdx, queue := range qs.queues { + if queue.requests.Length() == 0 && queue.requestsExecuting == 0 { + // Do not just decrement, the value could be quite outdated. + // It is safe to reset to zero in this case, because the next request + // will overwrite the zero with `qs.currentR`. + queue.nextDispatchR = 0 + continue + } + oldNextDispatchR := queue.nextDispatchR + queue.nextDispatchR -= rDecrement + if queue.nextDispatchR > oldNextDispatchR { + klog.ErrorS(errors.New("queue::nextDispatchR underflow"), "Underflow", "QS", qs.qCfg.Name, "queue", qIdx, "oldNextDispatchR", oldNextDispatchR, "newNextDispatchR", queue.nextDispatchR, "incrR", incrR) + success = false + } + queue.requests.Walk(func(req *request) bool { + oldArrivalR := req.arrivalR + req.arrivalR -= rDecrement + if req.arrivalR > oldArrivalR { + klog.ErrorS(errors.New("request::arrivalR underflow"), "Underflow", "QS", qs.qCfg.Name, "queue", qIdx, "request", *req, "oldArrivalR", oldArrivalR, "incrR", incrR) + success = false + } + return true + }) + } + metrics.AddEpochAdvance(ctx, qs.qCfg.Name, success) +} + +// getVirtualTimeRatio calculates the rate at which virtual time has +// been advancing, according to the logic in `doc.go`. +func (qs *queueSet) getVirtualTimeRatioLocked() float64 { + activeQueues := 0 + seatsRequested := 0 + for _, queue := range qs.queues { + // here we want the sum of the maximum width of the requests in this queue since our + // goal is to find the maximum rate at which the queue could work. + seatsRequested += (queue.seatsInUse + queue.requests.QueueSum().MaxSeatsSum) + if queue.requests.Length() > 0 || queue.requestsExecuting > 0 { + activeQueues++ + } + } + if activeQueues == 0 { + return 0 + } + return math.Min(float64(seatsRequested), float64(qs.dCfg.ConcurrencyLimit)) / float64(activeQueues) +} + +// timeoutOldRequestsAndRejectOrEnqueueLocked encapsulates the logic required +// to validate and enqueue a request for the queueSet/QueueSet: +// 1) Start with shuffle sharding, to pick a queue. +// 2) Reject old requests that have been waiting too long +// 3) Reject current request if there is not enough concurrency shares and +// we are at max queue length +// 4) If not rejected, create a request and enqueue +// returns the enqueud request on a successful enqueue +// returns nil in the case that there is no available concurrency or +// the queuelengthlimit has been reached +func (qs *queueSet) timeoutOldRequestsAndRejectOrEnqueueLocked(ctx context.Context, workEstimate *fqrequest.WorkEstimate, hashValue uint64, flowDistinguisher, fsName string, descr1, descr2 interface{}, queueNoteFn fq.QueueNoteFn) *request { + // Start with the shuffle sharding, to pick a queue. + queueIdx := qs.shuffleShardLocked(hashValue, descr1, descr2) + queue := qs.queues[queueIdx] + // The next step is the logic to reject requests that have been waiting too long + qs.removeTimedOutRequestsFromQueueToBoundLocked(queue, fsName) + // NOTE: currently timeout is only checked for each new request. This means that there can be + // requests that are in the queue longer than the timeout if there are no new requests + // We prefer the simplicity over the promptness, at least for now. + + defer qs.boundNextDispatchLocked(queue) + + // Create a request and enqueue + req := &request{ + qs: qs, + fsName: fsName, + flowDistinguisher: flowDistinguisher, + ctx: ctx, + decision: qs.promiseFactory(nil, ctx.Done(), decisionCancel), + arrivalTime: qs.clock.Now(), + arrivalR: qs.currentR, + queue: queue, + descr1: descr1, + descr2: descr2, + queueNoteFn: queueNoteFn, + workEstimate: qs.completeWorkEstimate(workEstimate), + } + if ok := qs.rejectOrEnqueueToBoundLocked(req); !ok { + return nil + } + metrics.ObserveQueueLength(ctx, qs.qCfg.Name, fsName, queue.requests.Length()) + return req +} + +// shuffleShardLocked uses shuffle sharding to select a queue index +// using the given hashValue and the shuffle sharding parameters of the queueSet. +func (qs *queueSet) shuffleShardLocked(hashValue uint64, descr1, descr2 interface{}) int { + var backHand [8]int + // Deal into a data structure, so that the order of visit below is not necessarily the order of the deal. + // This removes bias in the case of flows with overlapping hands. + hand := qs.dealer.DealIntoHand(hashValue, backHand[:]) + handSize := len(hand) + offset := qs.enqueues % handSize + qs.enqueues++ + bestQueueIdx := -1 + minQueueSeatSeconds := fqrequest.MaxSeatSeconds + for i := 0; i < handSize; i++ { + queueIdx := hand[(offset+i)%handSize] + queue := qs.queues[queueIdx] + queueSum := queue.requests.QueueSum() + + // this is the total amount of work in seat-seconds for requests + // waiting in this queue, we will select the queue with the minimum. + thisQueueSeatSeconds := queueSum.TotalWorkSum + klog.V(7).Infof("QS(%s): For request %#+v %#+v considering queue %d with sum: %#v and %d seats in use, nextDispatchR=%v", qs.qCfg.Name, descr1, descr2, queueIdx, queueSum, queue.seatsInUse, queue.nextDispatchR) + if thisQueueSeatSeconds < minQueueSeatSeconds { + minQueueSeatSeconds = thisQueueSeatSeconds + bestQueueIdx = queueIdx + } + } + if klogV := klog.V(6); klogV.Enabled() { + chosenQueue := qs.queues[bestQueueIdx] + klogV.Infof("QS(%s) at t=%s R=%v: For request %#+v %#+v chose queue %d, with sum: %#v & %d seats in use & nextDispatchR=%v", qs.qCfg.Name, qs.clock.Now().Format(nsTimeFmt), qs.currentR, descr1, descr2, bestQueueIdx, chosenQueue.requests.QueueSum(), chosenQueue.seatsInUse, chosenQueue.nextDispatchR) + } + return bestQueueIdx +} + +// removeTimedOutRequestsFromQueueToBoundLocked rejects old requests that have been enqueued +// past the requestWaitLimit +func (qs *queueSet) removeTimedOutRequestsFromQueueToBoundLocked(queue *queue, fsName string) { + timeoutCount := 0 + disqueueSeats := 0 + now := qs.clock.Now() + reqs := queue.requests + // reqs are sorted oldest -> newest + // can short circuit loop (break) if oldest requests are not timing out + // as newer requests also will not have timed out + + // now - requestWaitLimit = arrivalLimit + arrivalLimit := now.Add(-qs.qCfg.RequestWaitLimit) + reqs.Walk(func(req *request) bool { + if arrivalLimit.After(req.arrivalTime) { + if req.decision.Set(decisionReject) && req.removeFromQueueLocked() != nil { + timeoutCount++ + disqueueSeats += req.MaxSeats() + req.NoteQueued(false) + metrics.AddRequestsInQueues(req.ctx, qs.qCfg.Name, req.fsName, -1) + } + // we need to check if the next request has timed out. + return true + } + // since reqs are sorted oldest -> newest, we are done here. + return false + }) + + // remove timed out requests from queue + if timeoutCount > 0 { + qs.totRequestsWaiting -= timeoutCount + qs.totSeatsWaiting -= disqueueSeats + qs.reqsGaugePair.RequestsWaiting.Add(float64(-timeoutCount)) + qs.seatDemandIntegrator.Set(float64(qs.totSeatsInUse + qs.totSeatsWaiting)) + } +} + +// rejectOrEnqueueToBoundLocked rejects or enqueues the newly arrived +// request, which has been assigned to a queue. If up against the +// queue length limit and the concurrency limit then returns false. +// Otherwise enqueues and returns true. +func (qs *queueSet) rejectOrEnqueueToBoundLocked(request *request) bool { + queue := request.queue + curQueueLength := queue.requests.Length() + // rejects the newly arrived request if resource criteria not met + if qs.totSeatsInUse >= qs.dCfg.ConcurrencyLimit && + curQueueLength >= qs.qCfg.QueueLengthLimit { + return false + } + + qs.enqueueToBoundLocked(request) + return true +} + +// enqueues a request into its queue. +func (qs *queueSet) enqueueToBoundLocked(request *request) { + queue := request.queue + now := qs.clock.Now() + if queue.requests.Length() == 0 && queue.requestsExecuting == 0 { + // the queue’s start R is set to the virtual time. + queue.nextDispatchR = qs.currentR + klogV := klog.V(6) + if klogV.Enabled() { + klogV.Infof("QS(%s) at t=%s R=%v: initialized queue %d start R due to request %#+v %#+v", qs.qCfg.Name, now.Format(nsTimeFmt), queue.nextDispatchR, queue.index, request.descr1, request.descr2) + } + } + request.removeFromQueueLocked = queue.requests.Enqueue(request) + qs.totRequestsWaiting++ + qs.totSeatsWaiting += request.MaxSeats() + metrics.AddRequestsInQueues(request.ctx, qs.qCfg.Name, request.fsName, 1) + request.NoteQueued(true) + qs.reqsGaugePair.RequestsWaiting.Add(1) + qs.seatDemandIntegrator.Set(float64(qs.totSeatsInUse + qs.totSeatsWaiting)) +} + +// dispatchAsMuchAsPossibleLocked does as many dispatches as possible now. +func (qs *queueSet) dispatchAsMuchAsPossibleLocked() { + for qs.totRequestsWaiting != 0 && qs.totSeatsInUse < qs.dCfg.ConcurrencyLimit && qs.dispatchLocked() { + } +} + +func (qs *queueSet) dispatchSansQueueLocked(ctx context.Context, workEstimate *fqrequest.WorkEstimate, flowDistinguisher, fsName string, descr1, descr2 interface{}) *request { + // does not call metrics.SetDispatchMetrics because there is no queuing and thus no interesting virtual world + now := qs.clock.Now() + req := &request{ + qs: qs, + fsName: fsName, + flowDistinguisher: flowDistinguisher, + ctx: ctx, + startTime: now, + decision: qs.promiseFactory(decisionExecute, ctx.Done(), decisionCancel), + arrivalTime: now, + arrivalR: qs.currentR, + descr1: descr1, + descr2: descr2, + workEstimate: qs.completeWorkEstimate(workEstimate), + } + qs.totRequestsExecuting++ + qs.totSeatsInUse += req.MaxSeats() + metrics.AddRequestsExecuting(ctx, qs.qCfg.Name, fsName, 1) + metrics.AddRequestConcurrencyInUse(qs.qCfg.Name, fsName, req.MaxSeats()) + qs.reqsGaugePair.RequestsExecuting.Add(1) + qs.execSeatsGauge.Add(float64(req.MaxSeats())) + qs.seatDemandIntegrator.Set(float64(qs.totSeatsInUse + qs.totSeatsWaiting)) + klogV := klog.V(5) + if klogV.Enabled() { + klogV.Infof("QS(%s) at t=%s R=%v: immediate dispatch of request %q %#+v %#+v, qs will have %d executing", qs.qCfg.Name, now.Format(nsTimeFmt), qs.currentR, fsName, descr1, descr2, qs.totRequestsExecuting) + } + return req +} + +// dispatchLocked uses the Fair Queuing for Server Requests method to +// select a queue and dispatch the oldest request in that queue. The +// return value indicates whether a request was dequeued; this will +// be false when either all queues are empty or the request at the head +// of the next queue cannot be dispatched. +func (qs *queueSet) dispatchLocked() bool { + queue, request := qs.findDispatchQueueToBoundLocked() + if queue == nil { + return false + } + if request == nil { // This should never happen. But if it does... + return false + } + qs.totRequestsWaiting-- + qs.totSeatsWaiting -= request.MaxSeats() + metrics.AddRequestsInQueues(request.ctx, qs.qCfg.Name, request.fsName, -1) + request.NoteQueued(false) + qs.reqsGaugePair.RequestsWaiting.Add(-1) + defer qs.boundNextDispatchLocked(queue) + if !request.decision.Set(decisionExecute) { + qs.seatDemandIntegrator.Set(float64(qs.totSeatsInUse + qs.totSeatsWaiting)) + return true + } + request.startTime = qs.clock.Now() + // At this moment the request leaves its queue and starts + // executing. We do not recognize any interim state between + // "queued" and "executing". While that means "executing" + // includes a little overhead from this package, this is not a + // problem because other overhead is also included. + qs.totRequestsExecuting++ + qs.totSeatsInUse += request.MaxSeats() + queue.requestsExecuting++ + queue.seatsInUse += request.MaxSeats() + metrics.AddRequestsExecuting(request.ctx, qs.qCfg.Name, request.fsName, 1) + metrics.AddRequestConcurrencyInUse(qs.qCfg.Name, request.fsName, request.MaxSeats()) + qs.reqsGaugePair.RequestsExecuting.Add(1) + qs.execSeatsGauge.Add(float64(request.MaxSeats())) + qs.seatDemandIntegrator.Set(float64(qs.totSeatsInUse + qs.totSeatsWaiting)) + klogV := klog.V(6) + if klogV.Enabled() { + klogV.Infof("QS(%s) at t=%s R=%v: dispatching request %#+v %#+v work %v from queue %d with start R %v, queue will have %d waiting & %d requests occupying %d seats, set will have %d seats occupied", + qs.qCfg.Name, request.startTime.Format(nsTimeFmt), qs.currentR, request.descr1, request.descr2, + request.workEstimate, queue.index, queue.nextDispatchR, queue.requests.Length(), queue.requestsExecuting, queue.seatsInUse, qs.totSeatsInUse) + } + // When a request is dequeued for service -> qs.virtualStart += G * width + if request.totalWork() > rDecrement/100 { // A single increment should never be so big + klog.Errorf("QS(%s) at t=%s R=%v: dispatching request %#+v %#+v with implausibly high work %v from queue %d with start R %v", + qs.qCfg.Name, request.startTime.Format(nsTimeFmt), qs.currentR, request.descr1, request.descr2, + request.workEstimate, queue.index, queue.nextDispatchR) + } + queue.nextDispatchR += request.totalWork() + return true +} + +// canAccommodateSeatsLocked returns true if this queueSet has enough +// seats available to accommodate a request with the given number of seats, +// otherwise it returns false. +func (qs *queueSet) canAccommodateSeatsLocked(seats int) bool { + switch { + case seats > qs.dCfg.ConcurrencyLimit: + // we have picked the queue with the minimum virtual finish time, but + // the number of seats this request asks for exceeds the concurrency limit. + // TODO: this is a quick fix for now, once we have borrowing in place we will not need it + if qs.totRequestsExecuting == 0 { + // TODO: apply additional lateny associated with this request, as described in the KEP + return true + } + // wait for all "currently" executing requests in this queueSet + // to finish before we can execute this request. + return false + case qs.totSeatsInUse+seats > qs.dCfg.ConcurrencyLimit: + return false + } + + return true +} + +// findDispatchQueueToBoundLocked examines the queues in round robin order and +// returns the first one of those for which the virtual finish time of +// the oldest waiting request is minimal, and also returns that request. +// Returns nils if the head of the selected queue can not be dispatched now, +// in which case the caller does not need to follow up with`qs.boundNextDispatchLocked`. +func (qs *queueSet) findDispatchQueueToBoundLocked() (*queue, *request) { + minVirtualFinish := fqrequest.MaxSeatSeconds + sMin := fqrequest.MaxSeatSeconds + dsMin := fqrequest.MaxSeatSeconds + sMax := fqrequest.MinSeatSeconds + dsMax := fqrequest.MinSeatSeconds + var minQueue *queue + var minIndex int + nq := len(qs.queues) + for range qs.queues { + qs.robinIndex = (qs.robinIndex + 1) % nq + queue := qs.queues[qs.robinIndex] + oldestWaiting, _ := queue.requests.Peek() + if oldestWaiting != nil { + sMin = ssMin(sMin, queue.nextDispatchR) + sMax = ssMax(sMax, queue.nextDispatchR) + estimatedWorkInProgress := fqrequest.SeatsTimesDuration(float64(queue.seatsInUse), qs.estimatedServiceDuration) + dsMin = ssMin(dsMin, queue.nextDispatchR-estimatedWorkInProgress) + dsMax = ssMax(dsMax, queue.nextDispatchR-estimatedWorkInProgress) + currentVirtualFinish := queue.nextDispatchR + oldestWaiting.totalWork() + klog.V(11).InfoS("Considering queue to dispatch", "queueSet", qs.qCfg.Name, "queue", qs.robinIndex, "finishR", currentVirtualFinish) + if currentVirtualFinish < minVirtualFinish { + minVirtualFinish = currentVirtualFinish + minQueue = queue + minIndex = qs.robinIndex + } + } + } + + oldestReqFromMinQueue, _ := minQueue.requests.Peek() + if oldestReqFromMinQueue == nil { + // This cannot happen + klog.ErrorS(errors.New("selected queue is empty"), "Impossible", "queueSet", qs.qCfg.Name) + return nil, nil + } + if !qs.canAccommodateSeatsLocked(oldestReqFromMinQueue.MaxSeats()) { + // since we have not picked the queue with the minimum virtual finish + // time, we are not going to advance the round robin index here. + klogV := klog.V(4) + if klogV.Enabled() { + klogV.Infof("QS(%s): request %v %v seats %d cannot be dispatched from queue %d, waiting for currently executing requests to complete, %d requests are occupying %d seats and the limit is %d", + qs.qCfg.Name, oldestReqFromMinQueue.descr1, oldestReqFromMinQueue.descr2, oldestReqFromMinQueue.MaxSeats(), minQueue.index, qs.totRequestsExecuting, qs.totSeatsInUse, qs.dCfg.ConcurrencyLimit) + } + metrics.AddDispatchWithNoAccommodation(qs.qCfg.Name, oldestReqFromMinQueue.fsName) + return nil, nil + } + oldestReqFromMinQueue.removeFromQueueLocked() + + // If the requested final seats exceed capacity of that queue, + // we reduce them to current capacity and adjust additional latency + // to preserve the total amount of work. + if oldestReqFromMinQueue.workEstimate.FinalSeats > uint64(qs.dCfg.ConcurrencyLimit) { + finalSeats := uint64(qs.dCfg.ConcurrencyLimit) + additionalLatency := oldestReqFromMinQueue.workEstimate.finalWork.DurationPerSeat(float64(finalSeats)) + oldestReqFromMinQueue.workEstimate.FinalSeats = finalSeats + oldestReqFromMinQueue.workEstimate.AdditionalLatency = additionalLatency + } + + // we set the round robin indexing to start at the chose queue + // for the next round. This way the non-selected queues + // win in the case that the virtual finish times are the same + qs.robinIndex = minIndex + + if minQueue.nextDispatchR < oldestReqFromMinQueue.arrivalR { + klog.ErrorS(errors.New("dispatch before arrival"), "Inconceivable!", "QS", qs.qCfg.Name, "queue", minQueue.index, "dispatchR", minQueue.nextDispatchR, "request", oldestReqFromMinQueue) + } + metrics.SetDispatchMetrics(qs.qCfg.Name, qs.currentR.ToFloat(), minQueue.nextDispatchR.ToFloat(), sMin.ToFloat(), sMax.ToFloat(), dsMin.ToFloat(), dsMax.ToFloat()) + return minQueue, oldestReqFromMinQueue +} + +func ssMin(a, b fqrequest.SeatSeconds) fqrequest.SeatSeconds { + if a > b { + return b + } + return a +} + +func ssMax(a, b fqrequest.SeatSeconds) fqrequest.SeatSeconds { + if a < b { + return b + } + return a +} + +// finishRequestAndDispatchAsMuchAsPossible is a convenience method +// which calls finishRequest for a given request and then dispatches +// as many requests as possible. This is all of what needs to be done +// once a request finishes execution or is canceled. This returns a bool +// indicating whether the QueueSet is now idle. +func (qs *queueSet) finishRequestAndDispatchAsMuchAsPossible(req *request) bool { + qs.lockAndSyncTime(req.ctx) + defer qs.lock.Unlock() + + qs.finishRequestLocked(req) + qs.dispatchAsMuchAsPossibleLocked() + return qs.isIdleLocked() +} + +// finishRequestLocked is a callback that should be used when a +// previously dispatched request has completed it's service. This +// callback updates important state in the queueSet +func (qs *queueSet) finishRequestLocked(r *request) { + now := qs.clock.Now() + qs.totRequestsExecuting-- + metrics.AddRequestsExecuting(r.ctx, qs.qCfg.Name, r.fsName, -1) + qs.reqsGaugePair.RequestsExecuting.Add(-1) + + actualServiceDuration := now.Sub(r.startTime) + + // TODO: for now we keep the logic localized so it is easier to see + // how the counters are tracked for queueset and queue, in future we + // can refactor to move this function. + releaseSeatsLocked := func() { + defer qs.removeQueueIfEmptyLocked(r) + + qs.totSeatsInUse -= r.MaxSeats() + metrics.AddRequestConcurrencyInUse(qs.qCfg.Name, r.fsName, -r.MaxSeats()) + qs.execSeatsGauge.Add(-float64(r.MaxSeats())) + qs.seatDemandIntegrator.Set(float64(qs.totSeatsInUse + qs.totSeatsWaiting)) + if r.queue != nil { + r.queue.seatsInUse -= r.MaxSeats() + } + } + + defer func() { + klogV := klog.V(6) + if r.workEstimate.AdditionalLatency <= 0 { + // release the seats allocated to this request immediately + releaseSeatsLocked() + if !klogV.Enabled() { + } else if r.queue != nil { + klogV.Infof("QS(%s) at t=%s R=%v: request %#+v %#+v finished all use of %d seats, adjusted queue %d start R to %v due to service time %.9fs, queue will have %d requests with %#v waiting & %d requests occupying %d seats", + qs.qCfg.Name, now.Format(nsTimeFmt), qs.currentR, r.descr1, r.descr2, r.workEstimate.MaxSeats(), r.queue.index, + r.queue.nextDispatchR, actualServiceDuration.Seconds(), r.queue.requests.Length(), r.queue.requests.QueueSum(), r.queue.requestsExecuting, r.queue.seatsInUse) + } else { + klogV.Infof("QS(%s) at t=%s R=%v: request %#+v %#+v finished all use of %d seats, qs will have %d requests occupying %d seats", qs.qCfg.Name, now.Format(nsTimeFmt), qs.currentR, r.descr1, r.descr2, r.workEstimate.InitialSeats, qs.totRequestsExecuting, qs.totSeatsInUse) + } + return + } + + additionalLatency := r.workEstimate.AdditionalLatency + if !klogV.Enabled() { + } else if r.queue != nil { + klogV.Infof("QS(%s) at t=%s R=%v: request %#+v %#+v finished main use of %d seats but lingering on %d seats for %v seconds, adjusted queue %d start R to %v due to service time %.9fs, queue will have %d requests with %#v waiting & %d requests occupying %d seats", + qs.qCfg.Name, now.Format(nsTimeFmt), qs.currentR, r.descr1, r.descr2, r.workEstimate.InitialSeats, r.workEstimate.FinalSeats, additionalLatency.Seconds(), r.queue.index, + r.queue.nextDispatchR, actualServiceDuration.Seconds(), r.queue.requests.Length(), r.queue.requests.QueueSum(), r.queue.requestsExecuting, r.queue.seatsInUse) + } else { + klogV.Infof("QS(%s) at t=%s R=%v: request %#+v %#+v finished main use of %d seats but lingering on %d seats for %v seconds, qs will have %d requests occupying %d seats", qs.qCfg.Name, now.Format(nsTimeFmt), qs.currentR, r.descr1, r.descr2, r.workEstimate.InitialSeats, r.workEstimate.FinalSeats, additionalLatency.Seconds(), qs.totRequestsExecuting, qs.totSeatsInUse) + } + // EventAfterDuration will execute the event func in a new goroutine, + // so the seats allocated to this request will be released after + // AdditionalLatency elapses, this ensures that the additional + // latency has no impact on the user experience. + qs.clock.EventAfterDuration(func(_ time.Time) { + qs.lockAndSyncTime(r.ctx) + defer qs.lock.Unlock() + now := qs.clock.Now() + releaseSeatsLocked() + if !klogV.Enabled() { + } else if r.queue != nil { + klogV.Infof("QS(%s) at t=%s R=%v: request %#+v %#+v finished lingering on %d seats, queue %d will have %d requests with %#v waiting & %d requests occupying %d seats", + qs.qCfg.Name, now.Format(nsTimeFmt), qs.currentR, r.descr1, r.descr2, r.workEstimate.FinalSeats, r.queue.index, + r.queue.requests.Length(), r.queue.requests.QueueSum(), r.queue.requestsExecuting, r.queue.seatsInUse) + } else { + klogV.Infof("QS(%s) at t=%s R=%v: request %#+v %#+v finished lingering on %d seats, qs will have %d requests occupying %d seats", qs.qCfg.Name, now.Format(nsTimeFmt), qs.currentR, r.descr1, r.descr2, r.workEstimate.FinalSeats, qs.totRequestsExecuting, qs.totSeatsInUse) + } + qs.dispatchAsMuchAsPossibleLocked() + }, additionalLatency) + }() + + if r.queue != nil { + // request has finished, remove from requests executing + r.queue.requestsExecuting-- + + // When a request finishes being served, and the actual service time was S, + // the queue’s start R is decremented by (G - S)*width. + r.queue.nextDispatchR -= fqrequest.SeatsTimesDuration(float64(r.InitialSeats()), qs.estimatedServiceDuration-actualServiceDuration) + qs.boundNextDispatchLocked(r.queue) + } +} + +// boundNextDispatchLocked applies the anti-windup hack. +// We need a hack because all non-empty queues are allocated the same +// number of seats. A queue that can not use all those seats and does +// not go empty accumulates a progresively earlier `virtualStart` compared +// to queues that are using more than they are allocated. +// The following hack addresses the first side of that inequity, +// by insisting that dispatch in the virtual world not precede arrival. +func (qs *queueSet) boundNextDispatchLocked(queue *queue) { + oldestReqFromMinQueue, _ := queue.requests.Peek() + if oldestReqFromMinQueue == nil { + return + } + var virtualStartBound = oldestReqFromMinQueue.arrivalR + if queue.nextDispatchR < virtualStartBound { + if klogV := klog.V(4); klogV.Enabled() { + klogV.InfoS("AntiWindup tweaked queue", "QS", qs.qCfg.Name, "queue", queue.index, "time", qs.clock.Now().Format(nsTimeFmt), "requestDescr1", oldestReqFromMinQueue.descr1, "requestDescr2", oldestReqFromMinQueue.descr2, "newVirtualStart", virtualStartBound, "deltaVirtualStart", (virtualStartBound - queue.nextDispatchR)) + } + queue.nextDispatchR = virtualStartBound + } +} + +func (qs *queueSet) removeQueueIfEmptyLocked(r *request) { + if r.queue == nil { + return + } + + // If there are more queues than desired and this one has no + // requests then remove it + if len(qs.queues) > qs.qCfg.DesiredNumQueues && + r.queue.requests.Length() == 0 && + r.queue.requestsExecuting == 0 { + qs.queues = removeQueueAndUpdateIndexes(qs.queues, r.queue.index) + + // decrement here to maintain the invariant that (qs.robinIndex+1) % numQueues + // is the index of the next queue after the one last dispatched from + if qs.robinIndex >= r.queue.index { + qs.robinIndex-- + } + } +} + +// removeQueueAndUpdateIndexes uses reslicing to remove an index from a slice +// and then updates the 'index' field of the queues to be correct +func removeQueueAndUpdateIndexes(queues []*queue, index int) []*queue { + keptQueues := append(queues[:index], queues[index+1:]...) + for i := index; i < len(keptQueues); i++ { + keptQueues[i].index-- + } + return keptQueues +} + +func (qs *queueSet) Dump(includeRequestDetails bool) debug.QueueSetDump { + qs.lock.Lock() + defer qs.lock.Unlock() + d := debug.QueueSetDump{ + Queues: make([]debug.QueueDump, len(qs.queues)), + Waiting: qs.totRequestsWaiting, + Executing: qs.totRequestsExecuting, + SeatsInUse: qs.totSeatsInUse, + SeatsWaiting: qs.totSeatsWaiting, + Dispatched: qs.totRequestsDispatched, + Rejected: qs.totRequestsRejected, + Timedout: qs.totRequestsTimedout, + Cancelled: qs.totRequestsCancelled, + } + for i, q := range qs.queues { + d.Queues[i] = q.dumpLocked(includeRequestDetails) + } + return d +} + +func OnRequestDispatched(r fq.Request) { + req, ok := r.(*request) + if !ok { + return + } + + qs := req.qs + if qs != nil { + qs.lock.Lock() + defer qs.lock.Unlock() + qs.totRequestsDispatched++ + } +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/types.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/types.go new file mode 100644 index 0000000000..f1073b96b2 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/types.go @@ -0,0 +1,183 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package queueset + +import ( + "context" + "time" + + genericrequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/util/flowcontrol/debug" + fq "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing" + "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise" + fcrequest "k8s.io/apiserver/pkg/util/flowcontrol/request" +) + +// request is a temporary container for "requests" with additional +// tracking fields required for QueueSet functionality. +type request struct { + ctx context.Context + + qs *queueSet + + flowDistinguisher string + fsName string + + // The relevant queue. Is nil if this request did not go through + // a queue. + queue *queue + + // estimated amount of work of the request + workEstimate completedWorkEstimate + + // decision gets set to a `requestDecision` indicating what to do + // with this request. It gets set exactly once, when the request + // is removed from its queue. The value will be decisionReject, + // decisionCancel, or decisionExecute. + // + // decision.Set is called with the queueSet locked. + // decision.Get is called without the queueSet locked. + decision promise.WriteOnce + + // arrivalTime is the real time when the request entered this system + arrivalTime time.Time + + // descr1 and descr2 are not used in any logic but they appear in + // log messages + descr1, descr2 interface{} + + queueNoteFn fq.QueueNoteFn + + // The preceding fields are filled in at creation and not modified since; + // the following fields may be modified later and must only be accessed while + // holding the queueSet's lock. + + // Removes this request from its queue. If the request is not put into a + // a queue it will be nil. + removeFromQueueLocked removeFromFIFOFunc + + // arrivalR is R(arrivalTime). R is, confusingly, also called "virtual time". + // This field is meaningful only while the request is waiting in the virtual world. + arrivalR fcrequest.SeatSeconds + + // startTime is the real time when the request began executing + startTime time.Time + + // Indicates whether client has called Request::Wait() + waitStarted bool +} + +type completedWorkEstimate struct { + fcrequest.WorkEstimate + totalWork fcrequest.SeatSeconds // initial plus final work + finalWork fcrequest.SeatSeconds // only final work +} + +// queue is a sequence of requests that have arrived but not yet finished +// execution in both the real and virtual worlds. +type queue struct { + // The requests not yet executing in the real world are stored in a FIFO list. + requests fifo + + // nextDispatchR is the R progress meter reading at + // which the next request will be dispatched in the virtual world. + nextDispatchR fcrequest.SeatSeconds + + // requestsExecuting is the count in the real world. + requestsExecuting int + + // index is the position of this queue among those in its queueSet. + index int + + // seatsInUse is the total number of "seats" currently occupied + // by all the requests that are currently executing in this queue. + seatsInUse int +} + +// queueSum tracks the sum of initial seats, max seats, and +// totalWork from all requests in a given queue +type queueSum struct { + // InitialSeatsSum is the sum of InitialSeats + // associated with all requests in a given queue. + InitialSeatsSum int + + // MaxSeatsSum is the sum of MaxSeats + // associated with all requests in a given queue. + MaxSeatsSum int + + // TotalWorkSum is the sum of totalWork of the waiting requests + TotalWorkSum fcrequest.SeatSeconds +} + +func (req *request) totalWork() fcrequest.SeatSeconds { + return req.workEstimate.totalWork +} + +func (qs *queueSet) completeWorkEstimate(we *fcrequest.WorkEstimate) completedWorkEstimate { + finalWork := qs.computeFinalWork(we) + return completedWorkEstimate{ + WorkEstimate: *we, + totalWork: qs.computeInitialWork(we) + finalWork, + finalWork: finalWork, + } +} + +func (qs *queueSet) computeInitialWork(we *fcrequest.WorkEstimate) fcrequest.SeatSeconds { + return fcrequest.SeatsTimesDuration(float64(we.InitialSeats), qs.estimatedServiceDuration) +} + +func (qs *queueSet) computeFinalWork(we *fcrequest.WorkEstimate) fcrequest.SeatSeconds { + return fcrequest.SeatsTimesDuration(float64(we.FinalSeats), we.AdditionalLatency) +} + +func (q *queue) dumpLocked(includeDetails bool) debug.QueueDump { + digest := make([]debug.RequestDump, q.requests.Length()) + i := 0 + q.requests.Walk(func(r *request) bool { + // dump requests. + digest[i].MatchedFlowSchema = r.fsName + digest[i].FlowDistinguisher = r.flowDistinguisher + digest[i].ArriveTime = r.arrivalTime + digest[i].StartTime = r.startTime + digest[i].WorkEstimate = r.workEstimate.WorkEstimate + if includeDetails { + userInfo, _ := genericrequest.UserFrom(r.ctx) + digest[i].UserName = userInfo.GetName() + requestInfo, ok := genericrequest.RequestInfoFrom(r.ctx) + if ok { + digest[i].RequestInfo = *requestInfo + } + } + i++ + return true + }) + + sum := q.requests.QueueSum() + queueSum := debug.QueueSum{ + InitialSeatsSum: sum.InitialSeatsSum, + MaxSeatsSum: sum.MaxSeatsSum, + TotalWorkSum: sum.TotalWorkSum.String(), + } + + return debug.QueueDump{ + NextDispatchR: q.nextDispatchR.String(), + Requests: digest, + ExecutingRequests: q.requestsExecuting, + SeatsInUse: q.seatsInUse, + QueueSum: queueSum, + } +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/format/formatting.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/format/formatting.go new file mode 100644 index 0000000000..4944423738 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/format/formatting.go @@ -0,0 +1,231 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package format + +import ( + "bytes" + "encoding/json" + "fmt" + + flowcontrol "k8s.io/api/flowcontrol/v1beta3" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/endpoints/request" +) + +// This file provides an easy way to mark a value for formatting to +// `%s` in full detail IF it is printed but without costing a lot of +// CPU or memory if the value is NOT printed. The API Priority and +// Fairness API objects are formatted into JSON. The other types of +// objects here are formatted into golang source. + +// Stringer marks the given value for custom formatting by this package. +type Stringer struct{ val interface{} } + +// Fmt marks the given value for custom formatting by this package. +func Fmt(val interface{}) Stringer { + return Stringer{val} +} + +// String formats to a string in full detail +func (sr Stringer) String() string { + if sr.val == nil { + return "nil" + } + switch typed := sr.val.(type) { + case *flowcontrol.FlowSchema, + flowcontrol.FlowSchema, + flowcontrol.FlowSchemaSpec, + flowcontrol.FlowDistinguisherMethod, + *flowcontrol.FlowDistinguisherMethod, + *flowcontrol.PolicyRulesWithSubjects, + flowcontrol.PolicyRulesWithSubjects, + flowcontrol.Subject, + flowcontrol.ResourcePolicyRule, + flowcontrol.NonResourcePolicyRule, + flowcontrol.FlowSchemaCondition, + *flowcontrol.PriorityLevelConfiguration, + flowcontrol.PriorityLevelConfiguration, + flowcontrol.PriorityLevelConfigurationSpec, + *flowcontrol.LimitedPriorityLevelConfiguration, + flowcontrol.LimitedPriorityLevelConfiguration, + flowcontrol.LimitResponse, + *flowcontrol.QueuingConfiguration, + flowcontrol.QueuingConfiguration: + return ToJSON(sr.val) + case []user.Info: + return FmtUsers(typed) + case []*request.RequestInfo: + return FmtRequests(typed) + default: + return fmt.Sprintf("%#+v", sr.val) + } +} + +// ToJSON converts using encoding/json and handles errors by +// formatting them +func ToJSON(val interface{}) string { + bs, err := json.Marshal(val) + str := string(bs) + if err != nil { + str = str + "<" + err.Error() + ">" + } + return str +} + +// FmtPriorityLevelConfiguration returns a golang source expression +// equivalent to the given value +func FmtPriorityLevelConfiguration(pl *flowcontrol.PriorityLevelConfiguration) string { + if pl == nil { + return "nil" + } + var buf bytes.Buffer + buf.WriteString(fmt.Sprintf("&flowcontrolv1beta3.PriorityLevelConfiguration{ObjectMeta: %#+v, Spec: ", + pl.ObjectMeta)) + BufferPriorityLevelConfigurationSpec(&buf, &pl.Spec) + buf.WriteString(fmt.Sprintf(", Status: %#+v}", pl.Status)) + return buf.String() +} + +// FmtPriorityLevelConfigurationSpec returns a golang source +// expression equivalent to the given value +func FmtPriorityLevelConfigurationSpec(plSpec *flowcontrol.PriorityLevelConfigurationSpec) string { + var buf bytes.Buffer + BufferPriorityLevelConfigurationSpec(&buf, plSpec) + return buf.String() +} + +// BufferPriorityLevelConfigurationSpec writes a golang source +// expression for the given value to the given buffer +func BufferPriorityLevelConfigurationSpec(buf *bytes.Buffer, plSpec *flowcontrol.PriorityLevelConfigurationSpec) { + buf.WriteString(fmt.Sprintf("flowcontrolv1beta3.PriorityLevelConfigurationSpec{Type: %#v", plSpec.Type)) + if plSpec.Limited != nil { + buf.WriteString(fmt.Sprintf(", Limited: &flowcontrol.LimitedPriorityLevelConfiguration{NominalConcurrencyShares:%d, LimitResponse:flowcontrol.LimitResponse{Type:%#v", plSpec.Limited.NominalConcurrencyShares, plSpec.Limited.LimitResponse.Type)) + if plSpec.Limited.LimitResponse.Queuing != nil { + buf.WriteString(fmt.Sprintf(", Queuing:&%#+v", *plSpec.Limited.LimitResponse.Queuing)) + } + buf.WriteString(" } }") + } + buf.WriteString("}") +} + +// FmtFlowSchema produces a golang source expression of the value. +func FmtFlowSchema(fs *flowcontrol.FlowSchema) string { + if fs == nil { + return "nil" + } + var buf bytes.Buffer + buf.WriteString(fmt.Sprintf("&flowcontrolv1beta3.FlowSchema{ObjectMeta: %#+v, Spec: ", + fs.ObjectMeta)) + BufferFlowSchemaSpec(&buf, &fs.Spec) + buf.WriteString(fmt.Sprintf(", Status: %#+v}", fs.Status)) + return buf.String() +} + +// FmtFlowSchemaSpec produces a golang source expression equivalent to +// the given spec +func FmtFlowSchemaSpec(fsSpec *flowcontrol.FlowSchemaSpec) string { + var buf bytes.Buffer + BufferFlowSchemaSpec(&buf, fsSpec) + return buf.String() +} + +// BufferFlowSchemaSpec writes a golang source expression for the +// given value to the given buffer +func BufferFlowSchemaSpec(buf *bytes.Buffer, fsSpec *flowcontrol.FlowSchemaSpec) { + buf.WriteString(fmt.Sprintf("flowcontrolv1beta3.FlowSchemaSpec{PriorityLevelConfiguration: %#+v, MatchingPrecedence: %d, DistinguisherMethod: ", + fsSpec.PriorityLevelConfiguration, + fsSpec.MatchingPrecedence)) + if fsSpec.DistinguisherMethod == nil { + buf.WriteString("nil") + } else { + buf.WriteString(fmt.Sprintf("&%#+v", *fsSpec.DistinguisherMethod)) + } + buf.WriteString(", Rules: []flowcontrol.PolicyRulesWithSubjects{") + for idx, rule := range fsSpec.Rules { + if idx > 0 { + buf.WriteString(", ") + } + BufferFmtPolicyRulesWithSubjectsSlim(buf, rule) + } + buf.WriteString("}}") +} + +// FmtPolicyRulesWithSubjects produces a golang source expression of the value. +func FmtPolicyRulesWithSubjects(rule flowcontrol.PolicyRulesWithSubjects) string { + return "flowcontrolv1beta3.PolicyRulesWithSubjects" + FmtPolicyRulesWithSubjectsSlim(rule) +} + +// FmtPolicyRulesWithSubjectsSlim produces a golang source expression +// of the value but without the leading type name. See above for an +// example context where this is useful. +func FmtPolicyRulesWithSubjectsSlim(rule flowcontrol.PolicyRulesWithSubjects) string { + var buf bytes.Buffer + BufferFmtPolicyRulesWithSubjectsSlim(&buf, rule) + return buf.String() +} + +// BufferFmtPolicyRulesWithSubjectsSlim writes a golang source +// expression for the given value to the given buffer but excludes the +// leading type name +func BufferFmtPolicyRulesWithSubjectsSlim(buf *bytes.Buffer, rule flowcontrol.PolicyRulesWithSubjects) { + buf.WriteString("{Subjects: []flowcontrolv1beta3.Subject{") + for jdx, subj := range rule.Subjects { + if jdx > 0 { + buf.WriteString(", ") + } + buf.WriteString(fmt.Sprintf("{Kind: %q", subj.Kind)) + if subj.User != nil { + buf.WriteString(fmt.Sprintf(", User: &%#+v", *subj.User)) + } + if subj.Group != nil { + buf.WriteString(fmt.Sprintf(", Group: &%#+v", *subj.Group)) + } + if subj.ServiceAccount != nil { + buf.WriteString(fmt.Sprintf(", ServiceAccount: &%#+v", *subj.ServiceAccount)) + } + buf.WriteString("}") + } + buf.WriteString(fmt.Sprintf("}, ResourceRules: %#+v, NonResourceRules: %#+v}", rule.ResourceRules, rule.NonResourceRules)) +} + +// FmtUsers produces a golang source expression of the value. +func FmtUsers(list []user.Info) string { + var buf bytes.Buffer + buf.WriteString("[]user.Info{") + for idx, member := range list { + if idx > 0 { + buf.WriteString(", ") + } + buf.WriteString(fmt.Sprintf("%#+v", member)) + } + buf.WriteString("}") + return buf.String() +} + +// FmtRequests produces a golang source expression of the value. +func FmtRequests(list []*request.RequestInfo) string { + var buf bytes.Buffer + buf.WriteString("[]*request.RequestInfo{") + for idx, member := range list { + if idx > 0 { + buf.WriteString(", ") + } + buf.WriteString(fmt.Sprintf("%#+v", member)) + } + buf.WriteString("}") + return buf.String() +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/formatting.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/formatting.go new file mode 100644 index 0000000000..5b5b367bd9 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/formatting.go @@ -0,0 +1,40 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package flowcontrol + +import ( + "fmt" + + fcfmt "k8s.io/apiserver/pkg/util/flowcontrol/format" +) + +var _ fmt.GoStringer = RequestDigest{} + +// GoString produces a golang source expression of the value. +func (rd RequestDigest) GoString() string { + return fmt.Sprintf("RequestDigest{RequestInfo: %#+v, User: %#+v}", rd.RequestInfo, rd.User) +} + +var _ fmt.GoStringer = (*priorityLevelState)(nil) + +// GoString produces a golang source expression of the value. +func (pls *priorityLevelState) GoString() string { + if pls == nil { + return "nil" + } + return fmt.Sprintf("&priorityLevelState{pl:%s, qsCompleter:%#+v, queues:%#+v, quiescing:%#v, numPending:%d}", fcfmt.Fmt(pls.pl), pls.qsCompleter, pls.queues, pls.quiescing, pls.numPending) +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/interface.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/interface.go new file mode 100644 index 0000000000..1f33f02b07 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/interface.go @@ -0,0 +1,67 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +// Gauge is the methods of a gauge that are used by instrumented code. +type Gauge interface { + Set(float64) + Inc() + Dec() + Add(float64) + SetToCurrentTime() +} + +// RatioedGauge tracks ratios. +// The numerator is set/changed through the Gauge methods, +// and the denominator can be updated through the SetDenominator method. +// A ratio is tracked whenever the numerator or denominator is set/changed. +type RatioedGauge interface { + Gauge + + // SetDenominator sets the denominator to use until it is changed again + SetDenominator(float64) +} + +// RatioedGaugeVec creates related observers that are +// differentiated by a series of label values +type RatioedGaugeVec interface { + // NewForLabelValuesSafe makes a new vector member for the given tuple of label values, + // initialized with the given numerator and denominator. + // Unlike the usual Vec WithLabelValues method, this is intended to be called only + // once per vector member (at the start of its lifecycle). + // The "Safe" part is saying that the returned object will function properly after metric registration + // even if this method is called before registration. + NewForLabelValuesSafe(initialNumerator, initialDenominator float64, labelValues []string) RatioedGauge +} + +//////////////////////////////// Pairs //////////////////////////////// +// +// API Priority and Fairness tends to use RatioedGaugeVec members in pairs, +// one for requests waiting in a queue and one for requests being executed. +// The following definitions are a convenience layer that adds support for that +// particular pattern of usage. + +// RatioedGaugePair is a corresponding pair of gauges, one for the +// number of requests waiting in queue(s) and one for the number of +// requests being executed. +type RatioedGaugePair struct { + // RequestsWaiting is given observations of the number of currently queued requests + RequestsWaiting RatioedGauge + + // RequestsExecuting is given observations of the number of requests currently executing + RequestsExecuting RatioedGauge +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/metrics.go new file mode 100644 index 0000000000..7cb05df6c8 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/metrics.go @@ -0,0 +1,600 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "context" + "strconv" + "strings" + "sync" + "time" + + epmetrics "k8s.io/apiserver/pkg/endpoints/metrics" + apirequest "k8s.io/apiserver/pkg/endpoints/request" + compbasemetrics "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" + basemetricstestutil "k8s.io/component-base/metrics/testutil" +) + +const ( + namespace = "apiserver" + subsystem = "flowcontrol" +) + +const ( + requestKind = "request_kind" + priorityLevel = "priority_level" + flowSchema = "flow_schema" + phase = "phase" + LabelNamePhase = "phase" + LabelValueWaiting = "waiting" + LabelValueExecuting = "executing" +) + +var ( + queueLengthBuckets = []float64{0, 10, 25, 50, 100, 250, 500, 1000} + requestDurationSecondsBuckets = []float64{0, 0.005, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30} +) + +var registerMetrics sync.Once + +// Register all metrics. +func Register() { + registerMetrics.Do(func() { + for _, metric := range metrics { + legacyregistry.MustRegister(metric) + } + }) +} + +type resettable interface { + Reset() +} + +// Reset all resettable metrics to zero +func Reset() { + for _, metric := range metrics { + if rm, ok := metric.(resettable); ok { + rm.Reset() + } + } +} + +// GatherAndCompare the given metrics with the given Prometheus syntax expected value +func GatherAndCompare(expected string, metricNames ...string) error { + return basemetricstestutil.GatherAndCompare(legacyregistry.DefaultGatherer, strings.NewReader(expected), metricNames...) +} + +// Registerables is a slice of Registerable +type Registerables []compbasemetrics.Registerable + +// Append adds more +func (rs Registerables) Append(more ...compbasemetrics.Registerable) Registerables { + return append(rs, more...) +} + +var ( + apiserverRejectedRequestsTotal = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "rejected_requests_total", + Help: "Number of requests rejected by API Priority and Fairness subsystem", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema, "reason"}, + ) + apiserverDispatchedRequestsTotal = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "dispatched_requests_total", + Help: "Number of requests executed by API Priority and Fairness subsystem", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + // PriorityLevelExecutionSeatsGaugeVec creates observers of seats occupied throughout execution for priority levels + PriorityLevelExecutionSeatsGaugeVec = NewTimingRatioHistogramVec( + &compbasemetrics.TimingHistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "priority_level_seat_utilization", + Help: "Observations, at the end of every nanosecond, of utilization of seats for any stage of execution (but only initial stage for WATCHes)", + // Buckets for both 0.99 and 1.0 mean PromQL's histogram_quantile will reveal saturation + Buckets: []float64{0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 1}, + ConstLabels: map[string]string{phase: "executing"}, + StabilityLevel: compbasemetrics.ALPHA, + }, + priorityLevel, + ) + // PriorityLevelConcurrencyGaugeVec creates gauges of concurrency broken down by phase, priority level + PriorityLevelConcurrencyGaugeVec = NewTimingRatioHistogramVec( + &compbasemetrics.TimingHistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "priority_level_request_utilization", + Help: "Observations, at the end of every nanosecond, of number of requests (as a fraction of the relevant limit) waiting or in any stage of execution (but only initial stage for WATCHes)", + // For executing: the denominator will be seats, so this metric will skew low. + // For waiting: total queue capacity is generally quite generous, so this metric will skew low. + Buckets: []float64{0, 0.001, 0.003, 0.01, 0.03, 0.1, 0.25, 0.5, 0.75, 1}, + StabilityLevel: compbasemetrics.ALPHA, + }, + LabelNamePhase, priorityLevel, + ) + // readWriteConcurrencyGaugeVec creates ratioed gauges of requests/limit broken down by phase and mutating vs readonly + readWriteConcurrencyGaugeVec = NewTimingRatioHistogramVec( + &compbasemetrics.TimingHistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "read_vs_write_current_requests", + Help: "Observations, at the end of every nanosecond, of the number of requests (as a fraction of the relevant limit) waiting or in regular stage of execution", + // This metric will skew low for the same reason as the priority level metrics + // and also because APF has a combined limit for mutating and readonly. + Buckets: []float64{0, 0.001, 0.01, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 1}, + StabilityLevel: compbasemetrics.ALPHA, + }, + LabelNamePhase, requestKind, + ) + apiserverCurrentR = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "current_r", + Help: "R(time of last change)", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverDispatchR = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "dispatch_r", + Help: "R(time of last dispatch)", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverLatestS = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "latest_s", + Help: "S(most recently dispatched request)", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverNextSBounds = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "next_s_bounds", + Help: "min and max, over queues, of S(oldest waiting request in queue)", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, "bound"}, + ) + apiserverNextDiscountedSBounds = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "next_discounted_s_bounds", + Help: "min and max, over queues, of S(oldest waiting request in queue) - estimated work in progress", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, "bound"}, + ) + apiserverCurrentInqueueRequests = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "current_inqueue_requests", + Help: "Number of requests currently pending in queues of the API Priority and Fairness subsystem", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + apiserverRequestQueueLength = compbasemetrics.NewHistogramVec( + &compbasemetrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "request_queue_length_after_enqueue", + Help: "Length of queue in the API Priority and Fairness subsystem, as seen by each request after it is enqueued", + Buckets: queueLengthBuckets, + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + apiserverRequestConcurrencyLimit = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "request_concurrency_limit", + Help: "Shared concurrency limit in the API Priority and Fairness subsystem", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverCurrentExecutingRequests = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "current_executing_requests", + Help: "Number of requests in initial (for a WATCH) or any (for a non-WATCH) execution stage in the API Priority and Fairness subsystem", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + apiserverRequestConcurrencyInUse = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "request_concurrency_in_use", + Help: "Concurrency (number of seats) occupied by the currently executing (initial stage for a WATCH, any stage otherwise) requests in the API Priority and Fairness subsystem", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + apiserverRequestWaitingSeconds = compbasemetrics.NewHistogramVec( + &compbasemetrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "request_wait_duration_seconds", + Help: "Length of time a request spent waiting in its queue", + Buckets: requestDurationSecondsBuckets, + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema, "execute"}, + ) + apiserverRequestExecutionSeconds = compbasemetrics.NewHistogramVec( + &compbasemetrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "request_execution_seconds", + Help: "Duration of initial stage (for a WATCH) or any (for a non-WATCH) stage of request execution in the API Priority and Fairness subsystem", + Buckets: requestDurationSecondsBuckets, + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema, "type"}, + ) + watchCountSamples = compbasemetrics.NewHistogramVec( + &compbasemetrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "watch_count_samples", + Help: "count of watchers for mutating requests in API Priority and Fairness", + Buckets: []float64{0, 1, 10, 100, 1000, 10000}, + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + apiserverEpochAdvances = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "epoch_advance_total", + Help: "Number of times the queueset's progress meter jumped backward", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, "success"}, + ) + apiserverWorkEstimatedSeats = compbasemetrics.NewHistogramVec( + &compbasemetrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "work_estimated_seats", + Help: "Number of estimated seats (maximum of initial and final seats) associated with requests in API Priority and Fairness", + // the upper bound comes from the maximum number of seats a request + // can occupy which is currently set at 10. + Buckets: []float64{1, 2, 4, 10}, + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + apiserverDispatchWithNoAccommodation = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "request_dispatch_no_accommodation_total", + Help: "Number of times a dispatch attempt resulted in a non accommodation due to lack of available seats", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + apiserverNominalConcurrencyLimits = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "nominal_limit_seats", + Help: "Nominal number of execution seats configured for each priority level", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverMinimumConcurrencyLimits = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "lower_limit_seats", + Help: "Configured lower bound on number of execution seats available to each priority level", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverMaximumConcurrencyLimits = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "upper_limit_seats", + Help: "Configured upper bound on number of execution seats available to each priority level", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + ApiserverSeatDemands = NewTimingRatioHistogramVec( + &compbasemetrics.TimingHistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "demand_seats", + Help: "Observations, at the end of every nanosecond, of (the number of seats each priority level could use) / (nominal number of seats for that level)", + // Rationale for the bucket boundaries: + // For 0--1, evenly spaced and not too many; + // For 1--2, roughly powers of sqrt(sqrt(2)); + // For 2--6, roughly powers of sqrt(2); + // We need coverage over 1, but do not want too many buckets. + Buckets: []float64{0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.7, 2, 2.8, 4, 6}, + StabilityLevel: compbasemetrics.ALPHA, + }, + priorityLevel, + ) + apiserverSeatDemandHighWatermarks = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "demand_seats_high_watermark", + Help: "High watermark, over last adjustment period, of demand_seats", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverSeatDemandAverages = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "demand_seats_average", + Help: "Time-weighted average, over last adjustment period, of demand_seats", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverSeatDemandStandardDeviations = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "demand_seats_stdev", + Help: "Time-weighted standard deviation, over last adjustment period, of demand_seats", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverSeatDemandSmootheds = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "demand_seats_smoothed", + Help: "Smoothed seat demands", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverSeatDemandTargets = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "target_seats", + Help: "Seat allocation targets", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverFairFracs = compbasemetrics.NewGauge( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "seat_fair_frac", + Help: "Fair fraction of server's concurrency to allocate to each priority level that can use it", + StabilityLevel: compbasemetrics.ALPHA, + }) + apiserverCurrentConcurrencyLimits = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "current_limit_seats", + Help: "current derived number of execution seats available to each priority level", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + + metrics = Registerables{ + apiserverRejectedRequestsTotal, + apiserverDispatchedRequestsTotal, + apiserverCurrentR, + apiserverDispatchR, + apiserverLatestS, + apiserverNextSBounds, + apiserverNextDiscountedSBounds, + apiserverCurrentInqueueRequests, + apiserverRequestQueueLength, + apiserverRequestConcurrencyLimit, + apiserverRequestConcurrencyInUse, + apiserverCurrentExecutingRequests, + apiserverRequestWaitingSeconds, + apiserverRequestExecutionSeconds, + watchCountSamples, + apiserverEpochAdvances, + apiserverWorkEstimatedSeats, + apiserverDispatchWithNoAccommodation, + apiserverNominalConcurrencyLimits, + apiserverMinimumConcurrencyLimits, + apiserverMaximumConcurrencyLimits, + apiserverSeatDemandHighWatermarks, + apiserverSeatDemandAverages, + apiserverSeatDemandStandardDeviations, + apiserverSeatDemandSmootheds, + apiserverSeatDemandTargets, + apiserverFairFracs, + apiserverCurrentConcurrencyLimits, + }. + Append(PriorityLevelExecutionSeatsGaugeVec.metrics()...). + Append(PriorityLevelConcurrencyGaugeVec.metrics()...). + Append(readWriteConcurrencyGaugeVec.metrics()...). + Append(ApiserverSeatDemands.metrics()...) +) + +type indexOnce struct { + labelValues []string + once sync.Once + gauge RatioedGauge +} + +func (io *indexOnce) getGauge() RatioedGauge { + io.once.Do(func() { + io.gauge = readWriteConcurrencyGaugeVec.NewForLabelValuesSafe(0, 1, io.labelValues) + }) + return io.gauge +} + +var waitingReadonly = indexOnce{labelValues: []string{LabelValueWaiting, epmetrics.ReadOnlyKind}} +var executingReadonly = indexOnce{labelValues: []string{LabelValueExecuting, epmetrics.ReadOnlyKind}} +var waitingMutating = indexOnce{labelValues: []string{LabelValueWaiting, epmetrics.MutatingKind}} +var executingMutating = indexOnce{labelValues: []string{LabelValueExecuting, epmetrics.MutatingKind}} + +// GetWaitingReadonlyConcurrency returns the gauge of number of readonly requests waiting / limit on those. +var GetWaitingReadonlyConcurrency = waitingReadonly.getGauge + +// GetExecutingReadonlyConcurrency returns the gauge of number of executing readonly requests / limit on those. +var GetExecutingReadonlyConcurrency = executingReadonly.getGauge + +// GetWaitingMutatingConcurrency returns the gauge of number of mutating requests waiting / limit on those. +var GetWaitingMutatingConcurrency = waitingMutating.getGauge + +// GetExecutingMutatingConcurrency returns the gauge of number of executing mutating requests / limit on those. +var GetExecutingMutatingConcurrency = executingMutating.getGauge + +// AddRequestsInQueues adds the given delta to the gauge of the # of requests in the queues of the specified flowSchema and priorityLevel +func AddRequestsInQueues(ctx context.Context, priorityLevel, flowSchema string, delta int) { + apiserverCurrentInqueueRequests.WithLabelValues(priorityLevel, flowSchema).Add(float64(delta)) +} + +// AddRequestsExecuting adds the given delta to the gauge of executing requests of the given flowSchema and priorityLevel +func AddRequestsExecuting(ctx context.Context, priorityLevel, flowSchema string, delta int) { + apiserverCurrentExecutingRequests.WithLabelValues(priorityLevel, flowSchema).Add(float64(delta)) +} + +// SetCurrentR sets the current-R (virtualTime) gauge for the given priority level +func SetCurrentR(priorityLevel string, r float64) { + apiserverCurrentR.WithLabelValues(priorityLevel).Set(r) +} + +// SetLatestS sets the latest-S (virtual time of dispatched request) gauge for the given priority level +func SetDispatchMetrics(priorityLevel string, r, s, sMin, sMax, discountedSMin, discountedSMax float64) { + apiserverDispatchR.WithLabelValues(priorityLevel).Set(r) + apiserverLatestS.WithLabelValues(priorityLevel).Set(s) + apiserverNextSBounds.WithLabelValues(priorityLevel, "min").Set(sMin) + apiserverNextSBounds.WithLabelValues(priorityLevel, "max").Set(sMax) + apiserverNextDiscountedSBounds.WithLabelValues(priorityLevel, "min").Set(discountedSMin) + apiserverNextDiscountedSBounds.WithLabelValues(priorityLevel, "max").Set(discountedSMax) +} + +// AddRequestConcurrencyInUse adds the given delta to the gauge of concurrency in use by +// the currently executing requests of the given flowSchema and priorityLevel +func AddRequestConcurrencyInUse(priorityLevel, flowSchema string, delta int) { + apiserverRequestConcurrencyInUse.WithLabelValues(priorityLevel, flowSchema).Add(float64(delta)) +} + +// AddReject increments the # of rejected requests for flow control +func AddReject(ctx context.Context, priorityLevel, flowSchema, reason string) { + apiserverRejectedRequestsTotal.WithContext(ctx).WithLabelValues(priorityLevel, flowSchema, reason).Add(1) +} + +// AddDispatch increments the # of dispatched requests for flow control +func AddDispatch(ctx context.Context, priorityLevel, flowSchema string) { + apiserverDispatchedRequestsTotal.WithContext(ctx).WithLabelValues(priorityLevel, flowSchema).Add(1) +} + +// ObserveQueueLength observes the queue length for flow control +func ObserveQueueLength(ctx context.Context, priorityLevel, flowSchema string, length int) { + apiserverRequestQueueLength.WithContext(ctx).WithLabelValues(priorityLevel, flowSchema).Observe(float64(length)) +} + +// ObserveWaitingDuration observes the queue length for flow control +func ObserveWaitingDuration(ctx context.Context, priorityLevel, flowSchema, execute string, waitTime time.Duration) { + apiserverRequestWaitingSeconds.WithContext(ctx).WithLabelValues(priorityLevel, flowSchema, execute).Observe(waitTime.Seconds()) +} + +// ObserveExecutionDuration observes the execution duration for flow control +func ObserveExecutionDuration(ctx context.Context, priorityLevel, flowSchema string, executionTime time.Duration) { + reqType := "regular" + if requestInfo, ok := apirequest.RequestInfoFrom(ctx); ok && requestInfo.Verb == "watch" { + reqType = requestInfo.Verb + } + apiserverRequestExecutionSeconds.WithContext(ctx).WithLabelValues(priorityLevel, flowSchema, reqType).Observe(executionTime.Seconds()) +} + +// ObserveWatchCount notes a sampling of a watch count +func ObserveWatchCount(ctx context.Context, priorityLevel, flowSchema string, count int) { + watchCountSamples.WithLabelValues(priorityLevel, flowSchema).Observe(float64(count)) +} + +// AddEpochAdvance notes an advance of the progress meter baseline for a given priority level +func AddEpochAdvance(ctx context.Context, priorityLevel string, success bool) { + apiserverEpochAdvances.WithContext(ctx).WithLabelValues(priorityLevel, strconv.FormatBool(success)).Inc() +} + +// ObserveWorkEstimatedSeats notes a sampling of estimated seats associated with a request +func ObserveWorkEstimatedSeats(priorityLevel, flowSchema string, seats int) { + apiserverWorkEstimatedSeats.WithLabelValues(priorityLevel, flowSchema).Observe(float64(seats)) +} + +// AddDispatchWithNoAccommodation keeps track of number of times dispatch attempt results +// in a non accommodation due to lack of available seats. +func AddDispatchWithNoAccommodation(priorityLevel, flowSchema string) { + apiserverDispatchWithNoAccommodation.WithLabelValues(priorityLevel, flowSchema).Inc() +} + +func SetPriorityLevelConfiguration(priorityLevel string, nominalCL, minCL, maxCL int) { + apiserverRequestConcurrencyLimit.WithLabelValues(priorityLevel).Set(float64(nominalCL)) + apiserverNominalConcurrencyLimits.WithLabelValues(priorityLevel).Set(float64(nominalCL)) + apiserverMinimumConcurrencyLimits.WithLabelValues(priorityLevel).Set(float64(minCL)) + apiserverMaximumConcurrencyLimits.WithLabelValues(priorityLevel).Set(float64(maxCL)) +} + +func NotePriorityLevelConcurrencyAdjustment(priorityLevel string, seatDemandHWM, seatDemandAvg, seatDemandStdev, seatDemandSmoothed, seatDemandTarget float64, currentCL int) { + apiserverSeatDemandHighWatermarks.WithLabelValues(priorityLevel).Set(seatDemandHWM) + apiserverSeatDemandAverages.WithLabelValues(priorityLevel).Set(seatDemandAvg) + apiserverSeatDemandStandardDeviations.WithLabelValues(priorityLevel).Set(seatDemandStdev) + apiserverSeatDemandSmootheds.WithLabelValues(priorityLevel).Set(seatDemandSmoothed) + apiserverSeatDemandTargets.WithLabelValues(priorityLevel).Set(seatDemandTarget) + apiserverCurrentConcurrencyLimits.WithLabelValues(priorityLevel).Set(float64(currentCL)) +} + +func SetFairFrac(fairFrac float64) { + apiserverFairFracs.Set(fairFrac) +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/timing_ratio_histogram.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/timing_ratio_histogram.go new file mode 100644 index 0000000000..2275be6aa5 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/timing_ratio_histogram.go @@ -0,0 +1,226 @@ +/* +Copyright 2022 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 metrics + +import ( + "context" + "sync" + "time" + + compbasemetrics "k8s.io/component-base/metrics" + "k8s.io/klog/v2" +) + +// TimingRatioHistogram is essentially a gauge for a ratio where the client +// independently controls the numerator and denominator. +// When scraped it produces a histogram of samples of the ratio +// taken at the end of every nanosecond. +// `*TimingRatioHistogram` implements both Registerable and RatioedGauge. +type TimingRatioHistogram struct { + // The implementation is layered on TimingHistogram, + // adding the division by an occasionally adjusted denominator. + + // Registerable is the registerable aspect. + // That is the registerable aspect of the underlying TimingHistogram. + compbasemetrics.Registerable + + // timingRatioHistogramInner implements the RatioedGauge aspect. + timingRatioHistogramInner +} + +// TimingRatioHistogramOpts is the constructor parameters of a TimingRatioHistogram. +// The `TimingHistogramOpts.InitialValue` is the initial numerator. +type TimingRatioHistogramOpts struct { + compbasemetrics.TimingHistogramOpts + InitialDenominator float64 +} + +// timingRatioHistogramInner implements the instrumentation aspect +type timingRatioHistogramInner struct { + nowFunc func() time.Time + getGaugeOfRatio func() Gauge + sync.Mutex + // access only with mutex locked + numerator, denominator float64 +} + +var _ RatioedGauge = &timingRatioHistogramInner{} +var _ RatioedGauge = &TimingRatioHistogram{} +var _ compbasemetrics.Registerable = &TimingRatioHistogram{} + +// NewTimingHistogram returns an object which is TimingHistogram-like. However, nothing +// will be measured until the histogram is registered in at least one registry. +func NewTimingRatioHistogram(opts *TimingRatioHistogramOpts) *TimingRatioHistogram { + return NewTestableTimingRatioHistogram(time.Now, opts) +} + +// NewTestableTimingHistogram adds injection of the clock +func NewTestableTimingRatioHistogram(nowFunc func() time.Time, opts *TimingRatioHistogramOpts) *TimingRatioHistogram { + //nolint:govet // copylocks: assignment copies lock value to ratioedOpts: k8s.io/component-base/metrics.TimingHistogramOpts contains sync.Once contains sync.Mutex + ratioedOpts := opts.TimingHistogramOpts + ratioedOpts.InitialValue /= opts.InitialDenominator + th := compbasemetrics.NewTestableTimingHistogram(nowFunc, &ratioedOpts) + return &TimingRatioHistogram{ + Registerable: th, + timingRatioHistogramInner: timingRatioHistogramInner{ + nowFunc: nowFunc, + getGaugeOfRatio: func() Gauge { return th }, + numerator: opts.InitialValue, + denominator: opts.InitialDenominator, + }} +} + +func (trh *timingRatioHistogramInner) Set(numerator float64) { + trh.Lock() + defer trh.Unlock() + trh.numerator = numerator + ratio := numerator / trh.denominator + trh.getGaugeOfRatio().Set(ratio) +} + +func (trh *timingRatioHistogramInner) Add(deltaNumerator float64) { + trh.Lock() + defer trh.Unlock() + numerator := trh.numerator + deltaNumerator + trh.numerator = numerator + ratio := numerator / trh.denominator + trh.getGaugeOfRatio().Set(ratio) +} + +func (trh *timingRatioHistogramInner) Sub(deltaNumerator float64) { + trh.Add(-deltaNumerator) +} + +func (trh *timingRatioHistogramInner) Inc() { + trh.Add(1) +} + +func (trh *timingRatioHistogramInner) Dec() { + trh.Add(-1) +} + +func (trh *timingRatioHistogramInner) SetToCurrentTime() { + trh.Set(float64(trh.nowFunc().Sub(time.Unix(0, 0)))) +} + +func (trh *timingRatioHistogramInner) SetDenominator(denominator float64) { + trh.Lock() + defer trh.Unlock() + trh.denominator = denominator + ratio := trh.numerator / denominator + trh.getGaugeOfRatio().Set(ratio) +} + +// WithContext allows the normal TimingHistogram metric to pass in context. +// The context is no-op at the current level of development. +func (trh *timingRatioHistogramInner) WithContext(ctx context.Context) RatioedGauge { + return trh +} + +// TimingRatioHistogramVec is a collection of TimingRatioHistograms that differ +// only in label values. +// `*TimingRatioHistogramVec` implements both Registerable and RatioedGaugeVec. +type TimingRatioHistogramVec struct { + // promote only the Registerable methods + compbasemetrics.Registerable + // delegate is TimingHistograms of the ratio + delegate compbasemetrics.GaugeVecMetric +} + +var _ RatioedGaugeVec = &TimingRatioHistogramVec{} +var _ compbasemetrics.Registerable = &TimingRatioHistogramVec{} + +// NewTimingHistogramVec constructs a new vector. +// `opts.InitialValue` is the initial ratio, but this applies +// only for the tiny period of time until NewForLabelValuesSafe sets +// the ratio based on the given initial numerator and denominator. +// Thus there is a tiny splinter of time during member construction when +// its underlying TimingHistogram is given the initial numerator rather than +// the initial ratio (which is obviously a non-issue when both are zero). +// Note the difficulties associated with extracting a member +// before registering the vector. +func NewTimingRatioHistogramVec(opts *compbasemetrics.TimingHistogramOpts, labelNames ...string) *TimingRatioHistogramVec { + return NewTestableTimingRatioHistogramVec(time.Now, opts, labelNames...) +} + +// NewTestableTimingHistogramVec adds injection of the clock. +func NewTestableTimingRatioHistogramVec(nowFunc func() time.Time, opts *compbasemetrics.TimingHistogramOpts, labelNames ...string) *TimingRatioHistogramVec { + delegate := compbasemetrics.NewTestableTimingHistogramVec(nowFunc, opts, labelNames) + return &TimingRatioHistogramVec{ + Registerable: delegate, + delegate: delegate, + } +} + +func (v *TimingRatioHistogramVec) metrics() Registerables { + return Registerables{v} +} + +// NewForLabelValuesChecked will return an error if this vec is not hidden and not yet registered +// or there is a syntactic problem with the labelValues. +func (v *TimingRatioHistogramVec) NewForLabelValuesChecked(initialNumerator, initialDenominator float64, labelValues []string) (RatioedGauge, error) { + underMember, err := v.delegate.WithLabelValuesChecked(labelValues...) + if err != nil { + return noopRatioed{}, err + } + underMember.Set(initialNumerator / initialDenominator) + return &timingRatioHistogramInner{ + getGaugeOfRatio: func() Gauge { return underMember }, + numerator: initialNumerator, + denominator: initialDenominator, + }, nil +} + +// NewForLabelValuesSafe is the same as NewForLabelValuesChecked in cases where that does not +// return an error. When the unsafe version returns an error due to the vector not being +// registered yet, the safe version returns an object that implements its methods +// by looking up the relevant vector member in each call (thus getting a non-noop after registration). +// In the other error cases the object returned here is a noop. +func (v *TimingRatioHistogramVec) NewForLabelValuesSafe(initialNumerator, initialDenominator float64, labelValues []string) RatioedGauge { + tro, err := v.NewForLabelValuesChecked(initialNumerator, initialDenominator, labelValues) + if err == nil { + klog.V(3).InfoS("TimingRatioHistogramVec.NewForLabelValuesSafe hit the efficient case", "fqName", v.FQName(), "labelValues", labelValues) + return tro + } + if !compbasemetrics.ErrIsNotRegistered(err) { + klog.ErrorS(err, "Failed to extract TimingRatioHistogramVec member, using noop instead", "vectorname", v.FQName(), "labelValues", labelValues) + return tro + } + klog.V(3).InfoS("TimingRatioHistogramVec.NewForLabelValuesSafe hit the inefficient case", "fqName", v.FQName(), "labelValues", labelValues) + // At this point we know v.NewForLabelValuesChecked(..) returns a permanent noop, + // which we precisely want to avoid using. Instead, make our own gauge that + // fetches the element on every Set. + return &timingRatioHistogramInner{ + getGaugeOfRatio: func() Gauge { return v.delegate.WithLabelValues(labelValues...) }, + numerator: initialNumerator, + denominator: initialDenominator, + } +} + +type noopRatioed struct{} + +func (noopRatioed) Set(float64) {} +func (noopRatioed) Add(float64) {} +func (noopRatioed) Sub(float64) {} +func (noopRatioed) Inc() {} +func (noopRatioed) Dec() {} +func (noopRatioed) SetToCurrentTime() {} +func (noopRatioed) SetDenominator(float64) {} + +func (v *TimingRatioHistogramVec) Reset() { + v.delegate.Reset() +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/union_gauge.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/union_gauge.go new file mode 100644 index 0000000000..b01daaaaa5 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/union_gauge.go @@ -0,0 +1,56 @@ +/* +Copyright 2022 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 metrics + +type unionGauge []Gauge + +var _ Gauge = unionGauge(nil) + +// NewUnionGauge constructs a Gauge that delegates to all of the given Gauges +func NewUnionGauge(elts ...Gauge) Gauge { + return unionGauge(elts) +} + +func (ug unionGauge) Set(x float64) { + for _, gauge := range ug { + gauge.Set(x) + } +} + +func (ug unionGauge) Add(x float64) { + for _, gauge := range ug { + gauge.Add(x) + } +} + +func (ug unionGauge) Inc() { + for _, gauge := range ug { + gauge.Inc() + } +} + +func (ug unionGauge) Dec() { + for _, gauge := range ug { + gauge.Dec() + } +} + +func (ug unionGauge) SetToCurrentTime() { + for _, gauge := range ug { + gauge.SetToCurrentTime() + } +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/vec_element_pair.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/vec_element_pair.go new file mode 100644 index 0000000000..6dcef12c2f --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/vec_element_pair.go @@ -0,0 +1,25 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +// RatioedGaugeVecPhasedElementPair extracts a pair of elements that differ in handling phase +func RatioedGaugeVecPhasedElementPair(vec RatioedGaugeVec, initialWaitingDenominator, initialExecutingDenominator float64, labelValues []string) RatioedGaugePair { + return RatioedGaugePair{ + RequestsWaiting: vec.NewForLabelValuesSafe(0, initialWaitingDenominator, append([]string{LabelValueWaiting}, labelValues...)), + RequestsExecuting: vec.NewForLabelValuesSafe(0, initialExecutingDenominator, append([]string{LabelValueExecuting}, labelValues...)), + } +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/config.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/config.go new file mode 100644 index 0000000000..b6db19209b --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/config.go @@ -0,0 +1,92 @@ +/* +Copyright 2022 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 request + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + minimumSeats = 1 + maximumSeats = 10 + objectsPerSeat = 100.0 + watchesPerSeat = 10.0 + enableMutatingWorkEstimator = true +) + +var eventAdditionalDuration = 5 * time.Millisecond + +// WorkEstimatorConfig holds work estimator parameters. +type WorkEstimatorConfig struct { + *ListWorkEstimatorConfig `json:"listWorkEstimatorConfig,omitempty"` + *MutatingWorkEstimatorConfig `json:"mutatingWorkEstimatorConfig,omitempty"` + + // MinimumSeats is the minimum number of seats a request must occupy. + MinimumSeats uint64 `json:"minimumSeats,omitempty"` + // MaximumSeats is the maximum number of seats a request can occupy + // + // NOTE: work_estimate_seats_samples metric uses the value of maximumSeats + // as the upper bound, so when we change maximumSeats we should also + // update the buckets of the metric. + MaximumSeats uint64 `json:"maximumSeats,omitempty"` +} + +// ListWorkEstimatorConfig holds work estimator parameters related to list requests. +type ListWorkEstimatorConfig struct { + ObjectsPerSeat float64 `json:"objectsPerSeat,omitempty"` +} + +// MutatingWorkEstimatorConfig holds work estimator +// parameters related to watches of mutating objects. +type MutatingWorkEstimatorConfig struct { + // TODO(wojtekt): Remove it once we tune the algorithm to not fail + // scalability tests. + Enabled bool `json:"enable,omitempty"` + EventAdditionalDuration metav1.Duration `json:"eventAdditionalDurationMs,omitempty"` + WatchesPerSeat float64 `json:"watchesPerSeat,omitempty"` +} + +// DefaultWorkEstimatorConfig creates a new WorkEstimatorConfig with default values. +func DefaultWorkEstimatorConfig() *WorkEstimatorConfig { + return &WorkEstimatorConfig{ + MinimumSeats: minimumSeats, + MaximumSeats: maximumSeats, + ListWorkEstimatorConfig: defaultListWorkEstimatorConfig(), + MutatingWorkEstimatorConfig: defaultMutatingWorkEstimatorConfig(), + } +} + +// defaultListWorkEstimatorConfig creates a new ListWorkEstimatorConfig with default values. +func defaultListWorkEstimatorConfig() *ListWorkEstimatorConfig { + return &ListWorkEstimatorConfig{ObjectsPerSeat: objectsPerSeat} +} + +// defaultMutatingWorkEstimatorConfig creates a new MutatingWorkEstimatorConfig with default values. +func defaultMutatingWorkEstimatorConfig() *MutatingWorkEstimatorConfig { + return &MutatingWorkEstimatorConfig{ + Enabled: enableMutatingWorkEstimator, + EventAdditionalDuration: metav1.Duration{Duration: eventAdditionalDuration}, + WatchesPerSeat: watchesPerSeat, + } +} + +// eventAdditionalDuration converts eventAdditionalDurationMs to a time.Duration type. +func (c *MutatingWorkEstimatorConfig) eventAdditionalDuration() time.Duration { + return c.EventAdditionalDuration.Duration +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/list_work_estimator.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/list_work_estimator.go new file mode 100644 index 0000000000..130746a411 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/list_work_estimator.go @@ -0,0 +1,157 @@ +/* +Copyright 2021 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 request + +import ( + "math" + "net/http" + "net/url" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + apirequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/features" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/klog/v2" +) + +func newListWorkEstimator(countFn objectCountGetterFunc, config *WorkEstimatorConfig) WorkEstimatorFunc { + estimator := &listWorkEstimator{ + config: config, + countGetterFn: countFn, + } + return estimator.estimate +} + +type listWorkEstimator struct { + config *WorkEstimatorConfig + countGetterFn objectCountGetterFunc +} + +func (e *listWorkEstimator) estimate(r *http.Request, flowSchemaName, priorityLevelName string) WorkEstimate { + requestInfo, ok := apirequest.RequestInfoFrom(r.Context()) + if !ok { + // no RequestInfo should never happen, but to be on the safe side + // let's return maximumSeats + return WorkEstimate{InitialSeats: e.config.MaximumSeats} + } + + if requestInfo.Name != "" { + // Requests with metadata.name specified are usually executed as get + // requests in storage layer so their width should be 1. + // Example of such list requests: + // /apis/certificates.k8s.io/v1/certificatesigningrequests?fieldSelector=metadata.name%3Dcsr-xxs4m + // /api/v1/namespaces/test/configmaps?fieldSelector=metadata.name%3Dbig-deployment-1&limit=500&resourceVersion=0 + return WorkEstimate{InitialSeats: e.config.MinimumSeats} + } + + query := r.URL.Query() + listOptions := metav1.ListOptions{} + if err := metav1.Convert_url_Values_To_v1_ListOptions(&query, &listOptions, nil); err != nil { + klog.ErrorS(err, "Failed to convert options while estimating work for the list request") + + // This request is destined to fail in the validation layer, + // return maximumSeats for this request to be consistent. + return WorkEstimate{InitialSeats: e.config.MaximumSeats} + } + isListFromCache := !shouldListFromStorage(query, &listOptions) + + numStored, err := e.countGetterFn(key(requestInfo)) + switch { + case err == ObjectCountStaleErr: + // object count going stale is indicative of degradation, so we should + // be conservative here and allocate maximum seats to this list request. + // NOTE: if a CRD is removed, its count will go stale first and then the + // pruner will eventually remove the CRD from the cache. + return WorkEstimate{InitialSeats: e.config.MaximumSeats} + case err == ObjectCountNotFoundErr: + // there are multiple scenarios in which we can see this error: + // a. the type is truly unknown, a typo on the caller's part. + // b. the count has gone stale for too long and the pruner + // has removed the type from the cache. + // c. the type is an aggregated resource that is served by a + // different apiserver (thus its object count is not updated) + // we don't have a way to distinguish between those situations. + // However, in case c, the request is delegated to a different apiserver, + // and thus its cost for our server is minimal. To avoid the situation + // when aggregated API calls are overestimated, we allocate the minimum + // possible seats (see #109106 as an example when being more conservative + // led to problems). + return WorkEstimate{InitialSeats: e.config.MinimumSeats} + case err != nil: + // we should never be here since Get returns either ObjectCountStaleErr or + // ObjectCountNotFoundErr, return maximumSeats to be on the safe side. + klog.ErrorS(err, "Unexpected error from object count tracker") + return WorkEstimate{InitialSeats: e.config.MaximumSeats} + } + + limit := numStored + if utilfeature.DefaultFeatureGate.Enabled(features.APIListChunking) && listOptions.Limit > 0 && + listOptions.Limit < numStored { + limit = listOptions.Limit + } + + var estimatedObjectsToBeProcessed int64 + + switch { + case isListFromCache: + // TODO: For resources that implement indexes at the watchcache level, + // we need to adjust the cost accordingly + estimatedObjectsToBeProcessed = numStored + case listOptions.FieldSelector != "" || listOptions.LabelSelector != "": + estimatedObjectsToBeProcessed = numStored + limit + default: + estimatedObjectsToBeProcessed = 2 * limit + } + + // for now, our rough estimate is to allocate one seat to each 100 obejcts that + // will be processed by the list request. + // we will come up with a different formula for the transformation function and/or + // fine tune this number in future iteratons. + seats := uint64(math.Ceil(float64(estimatedObjectsToBeProcessed) / e.config.ObjectsPerSeat)) + + // make sure we never return a seat of zero + if seats < e.config.MinimumSeats { + seats = e.config.MinimumSeats + } + if seats > e.config.MaximumSeats { + seats = e.config.MaximumSeats + } + return WorkEstimate{InitialSeats: seats} +} + +func key(requestInfo *apirequest.RequestInfo) string { + groupResource := &schema.GroupResource{ + Group: requestInfo.APIGroup, + Resource: requestInfo.Resource, + } + return groupResource.String() +} + +// NOTICE: Keep in sync with shouldDelegateList function in +// +// staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go +func shouldListFromStorage(query url.Values, opts *metav1.ListOptions) bool { + resourceVersion := opts.ResourceVersion + match := opts.ResourceVersionMatch + pagingEnabled := utilfeature.DefaultFeatureGate.Enabled(features.APIListChunking) + hasContinuation := pagingEnabled && len(opts.Continue) > 0 + hasLimit := pagingEnabled && opts.Limit > 0 && resourceVersion != "0" + unsupportedMatch := match != "" && match != metav1.ResourceVersionMatchNotOlderThan + + return resourceVersion == "" || hasContinuation || hasLimit || unsupportedMatch +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/mutating_work_estimator.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/mutating_work_estimator.go new file mode 100644 index 0000000000..305f8e1ebb --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/mutating_work_estimator.go @@ -0,0 +1,149 @@ +/* +Copyright 2021 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 request + +import ( + "math" + "net/http" + "time" + + apirequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/util/flowcontrol/metrics" +) + +func newMutatingWorkEstimator(countFn watchCountGetterFunc, config *WorkEstimatorConfig) WorkEstimatorFunc { + estimator := &mutatingWorkEstimator{ + config: config, + countFn: countFn, + } + return estimator.estimate +} + +type mutatingWorkEstimator struct { + config *WorkEstimatorConfig + countFn watchCountGetterFunc +} + +func (e *mutatingWorkEstimator) estimate(r *http.Request, flowSchemaName, priorityLevelName string) WorkEstimate { + // TODO(wojtekt): Remove once we tune the algorithm to not fail + // scalability tests. + if !e.config.Enabled { + return WorkEstimate{ + InitialSeats: 1, + } + } + + requestInfo, ok := apirequest.RequestInfoFrom(r.Context()) + if !ok { + // no RequestInfo should never happen, but to be on the safe side + // let's return a large value. + return WorkEstimate{ + InitialSeats: 1, + FinalSeats: e.config.MaximumSeats, + AdditionalLatency: e.config.eventAdditionalDuration(), + } + } + + if isRequestExemptFromWatchEvents(requestInfo) { + return WorkEstimate{ + InitialSeats: e.config.MinimumSeats, + FinalSeats: 0, + AdditionalLatency: time.Duration(0), + } + } + + watchCount := e.countFn(requestInfo) + metrics.ObserveWatchCount(r.Context(), priorityLevelName, flowSchemaName, watchCount) + + // The cost of the request associated with the watchers of that event + // consists of three parts: + // - cost of going through the event change logic + // - cost of serialization of the event + // - cost of processing an event object for each watcher (e.g. filtering, + // sending data over network) + // We're starting simple to get some operational experience with it and + // we will work on tuning the algorithm later. Given that the actual work + // associated with processing watch events is happening in multiple + // goroutines (proportional to the number of watchers) that are all + // resumed at once, as a starting point we assume that each such goroutine + // is taking 1/Nth of a seat for M milliseconds. + // We allow the accounting of that work in P&F to be reshaped into another + // rectangle of equal area for practical reasons. + var finalSeats uint64 + var additionalLatency time.Duration + + // TODO: Make this unconditional after we tune the algorithm better. + // Technically, there is an overhead connected to processing an event after + // the request finishes even if there is a small number of watches. + // However, until we tune the estimation we want to stay on the safe side + // an avoid introducing additional latency for almost every single request. + if watchCount >= int(e.config.WatchesPerSeat) { + // TODO: As described in the KEP, we should take into account that not all + // events are equal and try to estimate the cost of a single event based on + // some historical data about size of events. + finalSeats = uint64(math.Ceil(float64(watchCount) / e.config.WatchesPerSeat)) + finalWork := SeatsTimesDuration(float64(finalSeats), e.config.eventAdditionalDuration()) + + // While processing individual events is highly parallel, + // the design/implementation of P&F has a couple limitations that + // make using this assumption in the P&F implementation very + // inefficient because: + // - we reserve max(initialSeats, finalSeats) for time of executing + // both phases of the request + // - even more importantly, when a given `wide` request is the one to + // be dispatched, we are not dispatching any other request until + // we accumulate enough seats to dispatch the nominated one, even + // if currently unoccupied seats would allow for dispatching some + // other requests in the meantime + // As a consequence of these, the wider the request, the more capacity + // will effectively be blocked and unused during dispatching and + // executing this request. + // + // To mitigate the impact of it, we're capping the maximum number of + // seats that can be assigned to a given request. Thanks to it: + // 1) we reduce the amount of seat-seconds that are "wasted" during + // dispatching and executing initial phase of the request + // 2) we are not changing the finalWork estimate - just potentially + // reshaping it to be narrower and longer. As long as the maximum + // seats setting will prevent dispatching too many requests at once + // to prevent overloading kube-apiserver (and/or etcd or the VM or + // a physical machine it is running on), we believe the relaxed + // version should be good enough to achieve the P&F goals. + // + // TODO: Confirm that the current cap of maximumSeats allow us to + // achieve the above. + if finalSeats > e.config.MaximumSeats { + finalSeats = e.config.MaximumSeats + } + additionalLatency = finalWork.DurationPerSeat(float64(finalSeats)) + } + + return WorkEstimate{ + InitialSeats: 1, + FinalSeats: finalSeats, + AdditionalLatency: additionalLatency, + } +} + +func isRequestExemptFromWatchEvents(requestInfo *apirequest.RequestInfo) bool { + // Creating token for service account does not produce any event, + // but still serviceaccounts can have multiple watchers. + if requestInfo.Resource == "serviceaccounts" && requestInfo.Subresource == "token" { + return true + } + return false +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/object_count_tracker.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/object_count_tracker.go new file mode 100644 index 0000000000..62a5e4f2d4 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/object_count_tracker.go @@ -0,0 +1,169 @@ +/* +Copyright 2021 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 request + +import ( + "errors" + "sync" + "time" + + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/klog/v2" + "k8s.io/utils/clock" +) + +const ( + // type deletion (it applies mostly to CRD) is not a very frequent + // operation so we can afford to prune the cache at a large interval. + // at the same time, we also want to make sure that the scalability + // tests hit this code path. + pruneInterval = 1 * time.Hour + + // the storage layer polls for object count at every 1m interval, we will allow + // up to 2-3 transient failures to get the latest count for a given resource. + staleTolerationThreshold = 3 * time.Minute +) + +var ( + // ObjectCountNotFoundErr is returned when the object count for + // a given resource is not being tracked. + ObjectCountNotFoundErr = errors.New("object count not found for the given resource") + + // ObjectCountStaleErr is returned when the object count for a + // given resource has gone stale due to transient failures. + ObjectCountStaleErr = errors.New("object count has gone stale for the given resource") +) + +// StorageObjectCountTracker is an interface that is used to keep track of +// of the total number of objects for each resource. +// {group}.{resource} is used as the key name to update and retrieve +// the total number of objects for a given resource. +type StorageObjectCountTracker interface { + // Set is invoked to update the current number of total + // objects for the given resource + Set(string, int64) + + // Get returns the total number of objects for the given resource. + // The following errors are returned: + // - if the count has gone stale for a given resource due to transient + // failures ObjectCountStaleErr is returned. + // - if the given resource is not being tracked then + // ObjectCountNotFoundErr is returned. + Get(string) (int64, error) + + // RunUntil starts all the necessary maintenance. + RunUntil(stopCh <-chan struct{}) +} + +// NewStorageObjectCountTracker returns an instance of +// StorageObjectCountTracker interface that can be used to +// keep track of the total number of objects for each resource. +func NewStorageObjectCountTracker() StorageObjectCountTracker { + return &objectCountTracker{ + clock: &clock.RealClock{}, + counts: map[string]*timestampedCount{}, + } +} + +// timestampedCount stores the count of a given resource with a last updated +// timestamp so we can prune it after it goes stale for certain threshold. +type timestampedCount struct { + count int64 + lastUpdatedAt time.Time +} + +// objectCountTracker implements StorageObjectCountTracker with +// reader/writer mutual exclusion lock. +type objectCountTracker struct { + clock clock.PassiveClock + + lock sync.RWMutex + counts map[string]*timestampedCount +} + +func (t *objectCountTracker) Set(groupResource string, count int64) { + if count <= -1 { + // a value of -1 indicates that the 'Count' call failed to contact + // the storage layer, in most cases this error can be transient. + // we will continue to work with the count that is in the cache + // up to a certain threshold defined by staleTolerationThreshold. + // in case this becomes a non transient error then the count for + // the given resource will will eventually be removed from + // the cache by the pruner. + return + } + + now := t.clock.Now() + + // lock for writing + t.lock.Lock() + defer t.lock.Unlock() + + if item, ok := t.counts[groupResource]; ok { + item.count = count + item.lastUpdatedAt = now + return + } + + t.counts[groupResource] = ×tampedCount{ + count: count, + lastUpdatedAt: now, + } +} + +func (t *objectCountTracker) Get(groupResource string) (int64, error) { + staleThreshold := t.clock.Now().Add(-staleTolerationThreshold) + + t.lock.RLock() + defer t.lock.RUnlock() + + if item, ok := t.counts[groupResource]; ok { + if item.lastUpdatedAt.Before(staleThreshold) { + return item.count, ObjectCountStaleErr + } + return item.count, nil + } + return 0, ObjectCountNotFoundErr +} + +// RunUntil runs all the necessary maintenance. +func (t *objectCountTracker) RunUntil(stopCh <-chan struct{}) { + wait.PollUntil( + pruneInterval, + func() (bool, error) { + // always prune at every pruneInterval + return false, t.prune(pruneInterval) + }, stopCh) + klog.InfoS("StorageObjectCountTracker pruner is exiting") +} + +func (t *objectCountTracker) prune(threshold time.Duration) error { + oldestLastUpdatedAtAllowed := t.clock.Now().Add(-threshold) + + // lock for writing + t.lock.Lock() + defer t.lock.Unlock() + + for groupResource, count := range t.counts { + if count.lastUpdatedAt.After(oldestLastUpdatedAtAllowed) { + continue + } + delete(t.counts, groupResource) + } + + return nil +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/seat_seconds.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/seat_seconds.go new file mode 100644 index 0000000000..e3a4017452 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/seat_seconds.go @@ -0,0 +1,65 @@ +/* +Copyright 2021 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 request + +import ( + "fmt" + "math" + "time" +) + +// SeatSeconds is a measure of work, in units of seat-seconds, using a fixed-point representation. +// `SeatSeconds(n)` represents `n/ssScale` seat-seconds. +// The `ssScale` constant is private to the implementation here, +// no other code should use it. +type SeatSeconds uint64 + +// MaxSeatsSeconds is the maximum representable value of SeatSeconds +const MaxSeatSeconds = SeatSeconds(math.MaxUint64) + +// MinSeatSeconds is the lowest representable value of SeatSeconds +const MinSeatSeconds = SeatSeconds(0) + +// SeatsTimeDuration produces the SeatSeconds value for the given factors. +// This is intended only to produce small values, increments in work +// rather than amount of work done since process start. +func SeatsTimesDuration(seats float64, duration time.Duration) SeatSeconds { + return SeatSeconds(math.Round(seats * float64(duration/time.Nanosecond) / (1e9 / ssScale))) +} + +// ToFloat converts to a floating-point representation. +// This conversion may lose precision. +func (ss SeatSeconds) ToFloat() float64 { + return float64(ss) / ssScale +} + +// DurationPerSeat returns duration per seat. +// This division may lose precision. +func (ss SeatSeconds) DurationPerSeat(seats float64) time.Duration { + return time.Duration(float64(ss) / seats * (float64(time.Second) / ssScale)) +} + +// String converts to a string. +// This is suitable for large as well as small values. +func (ss SeatSeconds) String() string { + const div = SeatSeconds(ssScale) + quo := ss / div + rem := ss - quo*div + return fmt.Sprintf("%d.%08dss", quo, rem) +} + +const ssScale = 1e8 diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/width.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/width.go new file mode 100644 index 0000000000..86f0425843 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/width.go @@ -0,0 +1,113 @@ +/* +Copyright 2021 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 request + +import ( + "fmt" + "net/http" + "time" + + apirequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/klog/v2" +) + +// WorkEstimate carries three of the four parameters that determine the work in a request. +// The fourth parameter is the duration of the initial phase of execution. +type WorkEstimate struct { + // InitialSeats is the number of seats occupied while the server is + // executing this request. + InitialSeats uint64 + + // FinalSeats is the number of seats occupied at the end, + // during the AdditionalLatency. + FinalSeats uint64 + + // AdditionalLatency specifies the additional duration the seats allocated + // to this request must be reserved after the given request had finished. + // AdditionalLatency should not have any impact on the user experience, the + // caller must not experience this additional latency. + AdditionalLatency time.Duration +} + +// MaxSeats returns the maximum number of seats the request occupies over the +// phases of being served. +func (we *WorkEstimate) MaxSeats() int { + if we.InitialSeats >= we.FinalSeats { + return int(we.InitialSeats) + } + + return int(we.FinalSeats) +} + +// objectCountGetterFunc represents a function that gets the total +// number of objects for a given resource. +type objectCountGetterFunc func(string) (int64, error) + +// watchCountGetterFunc represents a function that gets the total +// number of watchers potentially interested in a given request. +type watchCountGetterFunc func(*apirequest.RequestInfo) int + +// NewWorkEstimator estimates the work that will be done by a given request, +// if no WorkEstimatorFunc matches the given request then the default +// work estimate of 1 seat is allocated to the request. +func NewWorkEstimator(objectCountFn objectCountGetterFunc, watchCountFn watchCountGetterFunc, config *WorkEstimatorConfig) WorkEstimatorFunc { + estimator := &workEstimator{ + minimumSeats: config.MinimumSeats, + maximumSeats: config.MaximumSeats, + listWorkEstimator: newListWorkEstimator(objectCountFn, config), + mutatingWorkEstimator: newMutatingWorkEstimator(watchCountFn, config), + } + return estimator.estimate +} + +// WorkEstimatorFunc returns the estimated work of a given request. +// This function will be used by the Priority & Fairness filter to +// estimate the work of of incoming requests. +type WorkEstimatorFunc func(request *http.Request, flowSchemaName, priorityLevelName string) WorkEstimate + +func (e WorkEstimatorFunc) EstimateWork(r *http.Request, flowSchemaName, priorityLevelName string) WorkEstimate { + return e(r, flowSchemaName, priorityLevelName) +} + +type workEstimator struct { + // the minimum number of seats a request must occupy + minimumSeats uint64 + // the maximum number of seats a request can occupy + maximumSeats uint64 + // listWorkEstimator estimates work for list request(s) + listWorkEstimator WorkEstimatorFunc + // mutatingWorkEstimator calculates the width of mutating request(s) + mutatingWorkEstimator WorkEstimatorFunc +} + +func (e *workEstimator) estimate(r *http.Request, flowSchemaName, priorityLevelName string) WorkEstimate { + requestInfo, ok := apirequest.RequestInfoFrom(r.Context()) + if !ok { + klog.ErrorS(fmt.Errorf("no RequestInfo found in context"), "Failed to estimate work for the request", "URI", r.RequestURI) + // no RequestInfo should never happen, but to be on the safe side let's return maximumSeats + return WorkEstimate{InitialSeats: e.maximumSeats} + } + + switch requestInfo.Verb { + case "list": + return e.listWorkEstimator.EstimateWork(r, flowSchemaName, priorityLevelName) + case "create", "update", "patch", "delete": + return e.mutatingWorkEstimator.EstimateWork(r, flowSchemaName, priorityLevelName) + } + + return WorkEstimate{InitialSeats: e.minimumSeats} +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/rule.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/rule.go new file mode 100644 index 0000000000..a404d3286e --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/rule.go @@ -0,0 +1,203 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package flowcontrol + +import ( + "strings" + + flowcontrol "k8s.io/api/flowcontrol/v1beta3" + "k8s.io/apiserver/pkg/authentication/serviceaccount" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/endpoints/request" +) + +// Tests whether a given request and FlowSchema match. Nobody mutates +// either input. +func matchesFlowSchema(digest RequestDigest, flowSchema *flowcontrol.FlowSchema) bool { + for _, policyRule := range flowSchema.Spec.Rules { + if matchesPolicyRule(digest, &policyRule) { + return true + } + } + return false +} + +func matchesPolicyRule(digest RequestDigest, policyRule *flowcontrol.PolicyRulesWithSubjects) bool { + if !matchesASubject(digest.User, policyRule.Subjects) { + return false + } + if digest.RequestInfo.IsResourceRequest { + return matchesAResourceRule(digest.RequestInfo, policyRule.ResourceRules) + } + return matchesANonResourceRule(digest.RequestInfo, policyRule.NonResourceRules) +} + +func matchesASubject(user user.Info, subjects []flowcontrol.Subject) bool { + for _, subject := range subjects { + if matchesSubject(user, subject) { + return true + } + } + return false +} + +func matchesSubject(user user.Info, subject flowcontrol.Subject) bool { + switch subject.Kind { + case flowcontrol.SubjectKindUser: + return subject.User != nil && (subject.User.Name == flowcontrol.NameAll || subject.User.Name == user.GetName()) + case flowcontrol.SubjectKindGroup: + if subject.Group == nil { + return false + } + seek := subject.Group.Name + if seek == "*" { + return true + } + for _, userGroup := range user.GetGroups() { + if userGroup == seek { + return true + } + } + return false + case flowcontrol.SubjectKindServiceAccount: + if subject.ServiceAccount == nil { + return false + } + if subject.ServiceAccount.Name == flowcontrol.NameAll { + return serviceAccountMatchesNamespace(subject.ServiceAccount.Namespace, user.GetName()) + } + return serviceaccount.MatchesUsername(subject.ServiceAccount.Namespace, subject.ServiceAccount.Name, user.GetName()) + default: + return false + } +} + +// serviceAccountMatchesNamespace checks whether the provided service account username matches the namespace, without +// allocating. Use this when checking a service account namespace against a known string. +// This is copied from `k8s.io/apiserver/pkg/authentication/serviceaccount::MatchesUsername` and simplified to not check the name part. +func serviceAccountMatchesNamespace(namespace string, username string) bool { + const ( + ServiceAccountUsernamePrefix = "system:serviceaccount:" + ServiceAccountUsernameSeparator = ":" + ) + if !strings.HasPrefix(username, ServiceAccountUsernamePrefix) { + return false + } + username = username[len(ServiceAccountUsernamePrefix):] + + if !strings.HasPrefix(username, namespace) { + return false + } + username = username[len(namespace):] + + return strings.HasPrefix(username, ServiceAccountUsernameSeparator) +} + +func matchesAResourceRule(ri *request.RequestInfo, rules []flowcontrol.ResourcePolicyRule) bool { + for _, rr := range rules { + if matchesResourcePolicyRule(ri, rr) { + return true + } + } + return false +} + +func matchesResourcePolicyRule(ri *request.RequestInfo, policyRule flowcontrol.ResourcePolicyRule) bool { + if !matchPolicyRuleVerb(policyRule.Verbs, ri.Verb) { + return false + } + if !matchPolicyRuleResource(policyRule.Resources, ri.Resource, ri.Subresource) { + return false + } + if !matchPolicyRuleAPIGroup(policyRule.APIGroups, ri.APIGroup) { + return false + } + if len(ri.Namespace) == 0 { + return policyRule.ClusterScope + } + return containsString(ri.Namespace, policyRule.Namespaces, flowcontrol.NamespaceEvery) +} + +func matchesANonResourceRule(ri *request.RequestInfo, rules []flowcontrol.NonResourcePolicyRule) bool { + for _, rr := range rules { + if matchesNonResourcePolicyRule(ri, rr) { + return true + } + } + return false +} + +func matchesNonResourcePolicyRule(ri *request.RequestInfo, policyRule flowcontrol.NonResourcePolicyRule) bool { + if !matchPolicyRuleVerb(policyRule.Verbs, ri.Verb) { + return false + } + return matchPolicyRuleNonResourceURL(policyRule.NonResourceURLs, ri.Path) +} + +func matchPolicyRuleVerb(policyRuleVerbs []string, requestVerb string) bool { + return containsString(requestVerb, policyRuleVerbs, flowcontrol.VerbAll) +} + +func matchPolicyRuleNonResourceURL(policyRuleRequestURLs []string, requestPath string) bool { + for _, rulePath := range policyRuleRequestURLs { + if rulePath == flowcontrol.NonResourceAll || rulePath == requestPath { + return true + } + rulePrefix := strings.TrimSuffix(rulePath, "*") + if !strings.HasSuffix(rulePrefix, "/") { + rulePrefix = rulePrefix + "/" + } + if strings.HasPrefix(requestPath, rulePrefix) { + return true + } + } + return false +} + +func matchPolicyRuleAPIGroup(policyRuleAPIGroups []string, requestAPIGroup string) bool { + return containsString(requestAPIGroup, policyRuleAPIGroups, flowcontrol.APIGroupAll) +} + +func rsJoin(requestResource, requestSubresource string) string { + seekString := requestResource + if requestSubresource != "" { + seekString = requestResource + "/" + requestSubresource + } + return seekString +} + +func matchPolicyRuleResource(policyRuleRequestResources []string, requestResource, requestSubresource string) bool { + return containsString(rsJoin(requestResource, requestSubresource), policyRuleRequestResources, flowcontrol.ResourceAll) +} + +// containsString returns true if either `x` or `wildcard` is in +// `list`. The wildcard is not a pattern to match against `x`; rather +// the presence of the wildcard in the list is the caller's way of +// saying that all values of `x` should match the list. This function +// assumes that if `wildcard` is in `list` then it is the only member +// of the list, which is enforced by validation. +func containsString(x string, list []string, wildcard string) bool { + if len(list) == 1 && list[0] == wildcard { + return true + } + for _, y := range list { + if x == y { + return true + } + } + return false +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/watch_tracker.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/watch_tracker.go new file mode 100644 index 0000000000..b7b9c886bf --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/watch_tracker.go @@ -0,0 +1,233 @@ +/* +Copyright 2021 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 flowcontrol + +import ( + "net/http" + "sync" + + metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" + "k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apiserver/pkg/endpoints/request" + + "k8s.io/klog/v2" +) + +// readOnlyVerbs contains verbs for read-only requests. +var readOnlyVerbs = sets.NewString("get", "list", "watch", "proxy") + +// watchIdentifier identifies group of watches that are similar. +// As described in the "Priority and Fairness" KEP, we consider +// watches similar if they have the same resourceType, namespace +// and name. We ignore selectors as they have to be evaluated +// when processing an even anyway. +// +// TODO: For now we only track the number of watches registered +// in our kube-apiserver. Eventually we should consider sharing +// this information with other kube-apiserver as described in the +// KEP, but this isn't part of the first version. +type watchIdentifier struct { + apiGroup string + resource string + namespace string + name string +} + +// ForgetWatchFunc is a function that should be called to forget +// the previously registered watch from the watch tracker. +type ForgetWatchFunc func() + +// WatchTracker is an interface that allows tracking the number +// of watches in the system for the purpose of estimating the +// cost of incoming mutating requests. +type WatchTracker interface { + // RegisterWatch reqisters a watch based on the provided http.Request + // in the tracker. It returns the function that should be called + // to forget the watcher once it is finished. + RegisterWatch(r *http.Request) ForgetWatchFunc + + // GetInterestedWatchCount returns the number of watches that are + // potentially interested in a request with a given RequestInfo + // for the purpose of estimating cost of that request. + GetInterestedWatchCount(requestInfo *request.RequestInfo) int +} + +// builtinIndexes represents of set of indexes registered in +// watchcache that are indexing watches and increase speed of +// their processing. +// We define the indexes as a map from a resource to the path +// to the field in the object on which the index is built. +type builtinIndexes map[string]string + +func getBuiltinIndexes() builtinIndexes { + // The only existing indexes as of now are: + // - spec.nodeName for pods + // - metadata.Name for nodes, secrets and configmaps + // However, we can ignore the latter, because the requestInfo.Name + // is set for them (i.e. we already catch them correctly). + return map[string]string{ + "pods": "spec.nodeName", + } +} + +// watchTracker tracks the number of watches in the system for +// the purpose of estimating the cost of incoming mutating requests. +type watchTracker struct { + // indexes represents a set of registered indexes. + // It can't change after creation. + indexes builtinIndexes + + lock sync.Mutex + watchCount map[watchIdentifier]int +} + +func NewWatchTracker() WatchTracker { + return &watchTracker{ + indexes: getBuiltinIndexes(), + watchCount: make(map[watchIdentifier]int), + } +} + +const ( + unsetValue = "" +) + +func getIndexValue(r *http.Request, field string) string { + opts := metainternalversion.ListOptions{} + if err := scheme.ParameterCodec.DecodeParameters(r.URL.Query(), metav1.SchemeGroupVersion, &opts); err != nil { + klog.Warningf("Couldn't parse list options for %v: %v", r.URL.Query(), err) + return unsetValue + } + if opts.FieldSelector == nil { + return unsetValue + } + if value, ok := opts.FieldSelector.RequiresExactMatch(field); ok { + return value + } + return unsetValue +} + +type indexValue struct { + resource string + value string +} + +// RegisterWatch implements WatchTracker interface. +func (w *watchTracker) RegisterWatch(r *http.Request) ForgetWatchFunc { + requestInfo, ok := request.RequestInfoFrom(r.Context()) + if !ok || requestInfo == nil || requestInfo.Verb != "watch" { + return nil + } + + var index *indexValue + if indexField, ok := w.indexes[requestInfo.Resource]; ok { + index = &indexValue{ + resource: requestInfo.Resource, + value: getIndexValue(r, indexField), + } + } + + identifier := &watchIdentifier{ + apiGroup: requestInfo.APIGroup, + resource: requestInfo.Resource, + namespace: requestInfo.Namespace, + name: requestInfo.Name, + } + + w.lock.Lock() + defer w.lock.Unlock() + w.updateIndexLocked(identifier, index, 1) + return w.forgetWatch(identifier, index) +} + +func (w *watchTracker) updateIndexLocked(identifier *watchIdentifier, index *indexValue, incr int) { + if index == nil { + w.watchCount[*identifier] += incr + } else { + // For resources with defined index, for a given watch event we are + // only processing the watchers that: + // (a) do not specify field selector for an index field + // (b) do specify field selector with the value equal to the value + // coming from the processed object + // + // TODO(wojtek-t): For the sake of making progress and initially + // simplifying the implementation, we approximate (b) for all values + // as the value for an empty string. The assumption we're making here + // is that the difference between the actual number of watchers that + // will be processed, i.e. (a)+(b) above and the one from our + // approximation i.e. (a)+[(b) for field value of ""] will be small. + // This seem to be true in almost all production clusters, which makes + // it a reasonable first step simplification to unblock progres on it. + if index.value == unsetValue || index.value == "" { + w.watchCount[*identifier] += incr + } + } +} + +func (w *watchTracker) forgetWatch(identifier *watchIdentifier, index *indexValue) ForgetWatchFunc { + return func() { + w.lock.Lock() + defer w.lock.Unlock() + + w.updateIndexLocked(identifier, index, -1) + if w.watchCount[*identifier] == 0 { + delete(w.watchCount, *identifier) + } + } +} + +// GetInterestedWatchCount implements WatchTracker interface. +// +// TODO(wojtek-t): As of now, requestInfo for object creation (POST) doesn't +// contain the Name field set. Figure out if we can somehow get it for the +// more accurate cost estimation. +// +// TODO(wojtek-t): Figure out how to approach DELETECOLLECTION calls. +func (w *watchTracker) GetInterestedWatchCount(requestInfo *request.RequestInfo) int { + if requestInfo == nil || readOnlyVerbs.Has(requestInfo.Verb) { + return 0 + } + + result := 0 + // The watches that we're interested in include: + // - watches for all objects of a resource type (no namespace and name specified) + // - watches for all objects of a resource type in the same namespace (no name specified) + // - watched interested in this particular object + identifier := &watchIdentifier{ + apiGroup: requestInfo.APIGroup, + resource: requestInfo.Resource, + } + + w.lock.Lock() + defer w.lock.Unlock() + + result += w.watchCount[*identifier] + + if requestInfo.Namespace != "" { + identifier.namespace = requestInfo.Namespace + result += w.watchCount[*identifier] + } + + if requestInfo.Name != "" { + identifier.name = requestInfo.Name + result += w.watchCount[*identifier] + } + + return result +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flushwriter/doc.go b/vendor/k8s.io/apiserver/pkg/util/flushwriter/doc.go new file mode 100644 index 0000000000..f81e09a29c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flushwriter/doc.go @@ -0,0 +1,19 @@ +/* +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 flushwriter implements a wrapper for a writer that flushes on every +// write if that writer implements the io.Flusher interface +package flushwriter // import "k8s.io/apiserver/pkg/util/flushwriter" diff --git a/vendor/k8s.io/apiserver/pkg/util/flushwriter/writer.go b/vendor/k8s.io/apiserver/pkg/util/flushwriter/writer.go new file mode 100644 index 0000000000..748bd01085 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flushwriter/writer.go @@ -0,0 +1,53 @@ +/* +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 flushwriter + +import ( + "io" + "net/http" +) + +// Wrap wraps an io.Writer into a writer that flushes after every write if +// the writer implements the Flusher interface. +func Wrap(w io.Writer) io.Writer { + fw := &flushWriter{ + writer: w, + } + if flusher, ok := w.(http.Flusher); ok { + fw.flusher = flusher + } + return fw +} + +// flushWriter provides wrapper for responseWriter with HTTP streaming capabilities +type flushWriter struct { + flusher http.Flusher + writer io.Writer +} + +// Write is a FlushWriter implementation of the io.Writer that sends any buffered +// data to the client. +func (fw *flushWriter) Write(p []byte) (n int, err error) { + n, err = fw.writer.Write(p) + if err != nil { + return + } + if fw.flusher != nil { + fw.flusher.Flush() + } + return +} diff --git a/vendor/k8s.io/apiserver/pkg/util/shufflesharding/shufflesharding.go b/vendor/k8s.io/apiserver/pkg/util/shufflesharding/shufflesharding.go new file mode 100644 index 0000000000..6ef4ed8900 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/shufflesharding/shufflesharding.go @@ -0,0 +1,107 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package shufflesharding + +import ( + "fmt" + "math" +) + +// MaxHashBits is the max bit length which can be used from hash value. +// If we use all bits of hash value, the critical(last) card shuffled by +// Dealer will be uneven to 2:3 (first half:second half) at most, +// in order to reduce this unevenness to 32:33, we set MaxHashBits to 60 here. +const MaxHashBits = 60 + +// RequiredEntropyBits makes a quick and slightly conservative estimate of the number +// of bits of hash value that are consumed in shuffle sharding a deck of the given size +// to a hand of the given size. The result is meaningful only if +// 1 <= handSize <= deckSize <= 1<<26. +func RequiredEntropyBits(deckSize, handSize int) int { + return int(math.Ceil(math.Log2(float64(deckSize)) * float64(handSize))) +} + +// Dealer contains some necessary parameters and provides some methods for shuffle sharding. +// Dealer is thread-safe. +type Dealer struct { + deckSize int + handSize int +} + +// NewDealer will create a Dealer with the given deckSize and handSize, will return error when +// deckSize or handSize is invalid as below. +// 1. deckSize or handSize is not positive +// 2. handSize is greater than deckSize +// 3. deckSize is impractically large (greater than 1<<26) +// 4. required entropy bits of deckSize and handSize is greater than MaxHashBits +func NewDealer(deckSize, handSize int) (*Dealer, error) { + if deckSize <= 0 || handSize <= 0 { + return nil, fmt.Errorf("deckSize %d or handSize %d is not positive", deckSize, handSize) + } + if handSize > deckSize { + return nil, fmt.Errorf("handSize %d is greater than deckSize %d", handSize, deckSize) + } + if deckSize > 1<<26 { + return nil, fmt.Errorf("deckSize %d is impractically large", deckSize) + } + if RequiredEntropyBits(deckSize, handSize) > MaxHashBits { + return nil, fmt.Errorf("required entropy bits of deckSize %d and handSize %d is greater than %d", deckSize, handSize, MaxHashBits) + } + + return &Dealer{ + deckSize: deckSize, + handSize: handSize, + }, nil +} + +// Deal shuffles a card deck and deals a hand of cards, using the given hashValue as the source of entropy. +// The deck size and hand size are properties of the Dealer. +// This function synchronously makes sequential calls to pick, one for each dealt card. +// Each card is identified by an integer in the range [0, deckSize). +// For example, for deckSize=128 and handSize=4 this function might call pick(14); pick(73); pick(119); pick(26). +func (d *Dealer) Deal(hashValue uint64, pick func(int)) { + // 15 is the largest possible value of handSize + var remainders [15]int + + for i := 0; i < d.handSize; i++ { + hashValueNext := hashValue / uint64(d.deckSize-i) + remainders[i] = int(hashValue - uint64(d.deckSize-i)*hashValueNext) + hashValue = hashValueNext + } + + for i := 0; i < d.handSize; i++ { + card := remainders[i] + for j := i; j > 0; j-- { + if card >= remainders[j-1] { + card++ + } + } + pick(card) + } +} + +// DealIntoHand shuffles and deals according to the Dealer's parameters, +// using the given hashValue as the source of entropy and then +// returns the dealt cards as a slice of `int`. +// If `hand` has the correct length as Dealer's handSize, it will be used as-is and no allocations will be made. +// If `hand` is nil or too small, it will be extended (performing an allocation). +// If `hand` is too large, a sub-slice will be returned. +func (d *Dealer) DealIntoHand(hashValue uint64, hand []int) []int { + h := hand[:0] + d.Deal(hashValue, func(card int) { h = append(h, card) }) + return h +} diff --git a/vendor/k8s.io/apiserver/pkg/util/webhook/webhook.go b/vendor/k8s.io/apiserver/pkg/util/webhook/webhook.go index 06a74c1cd3..45143bf6ef 100644 --- a/vendor/k8s.io/apiserver/pkg/util/webhook/webhook.go +++ b/vendor/k8s.io/apiserver/pkg/util/webhook/webhook.go @@ -121,7 +121,7 @@ func WithExponentialBackoff(ctx context.Context, retryBackoff wait.Backoff, webh // having a webhook error allows us to track the last actual webhook error for requests that // are later cancelled or time out. var webhookErr error - err := wait.ExponentialBackoffWithContext(ctx, retryBackoff, func() (bool, error) { + err := wait.ExponentialBackoffWithContext(ctx, retryBackoff, func(_ context.Context) (bool, error) { webhookErr = webhookFn() if shouldRetry(webhookErr) { return false, nil diff --git a/vendor/k8s.io/apiserver/pkg/util/wsstream/conn.go b/vendor/k8s.io/apiserver/pkg/util/wsstream/conn.go new file mode 100644 index 0000000000..09f54a49c7 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/wsstream/conn.go @@ -0,0 +1,350 @@ +/* +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 wsstream + +import ( + "encoding/base64" + "fmt" + "io" + "net/http" + "regexp" + "strings" + "time" + + "golang.org/x/net/websocket" + "k8s.io/klog/v2" + + "k8s.io/apimachinery/pkg/util/runtime" +) + +// The Websocket subprotocol "channel.k8s.io" prepends each binary message with a byte indicating +// the channel number (zero indexed) the message was sent on. Messages in both directions should +// prefix their messages with this channel byte. When used for remote execution, the channel numbers +// are by convention defined to match the POSIX file-descriptors assigned to STDIN, STDOUT, and STDERR +// (0, 1, and 2). No other conversion is performed on the raw subprotocol - writes are sent as they +// are received by the server. +// +// Example client session: +// +// CONNECT http://server.com with subprotocol "channel.k8s.io" +// WRITE []byte{0, 102, 111, 111, 10} # send "foo\n" on channel 0 (STDIN) +// READ []byte{1, 10} # receive "\n" on channel 1 (STDOUT) +// CLOSE +const ChannelWebSocketProtocol = "channel.k8s.io" + +// The Websocket subprotocol "base64.channel.k8s.io" base64 encodes each message with a character +// indicating the channel number (zero indexed) the message was sent on. Messages in both directions +// should prefix their messages with this channel char. When used for remote execution, the channel +// numbers are by convention defined to match the POSIX file-descriptors assigned to STDIN, STDOUT, +// and STDERR ('0', '1', and '2'). The data received on the server is base64 decoded (and must be +// be valid) and data written by the server to the client is base64 encoded. +// +// Example client session: +// +// CONNECT http://server.com with subprotocol "base64.channel.k8s.io" +// WRITE []byte{48, 90, 109, 57, 118, 67, 103, 111, 61} # send "foo\n" (base64: "Zm9vCgo=") on channel '0' (STDIN) +// READ []byte{49, 67, 103, 61, 61} # receive "\n" (base64: "Cg==") on channel '1' (STDOUT) +// CLOSE +const Base64ChannelWebSocketProtocol = "base64.channel.k8s.io" + +type codecType int + +const ( + rawCodec codecType = iota + base64Codec +) + +type ChannelType int + +const ( + IgnoreChannel ChannelType = iota + ReadChannel + WriteChannel + ReadWriteChannel +) + +var ( + // connectionUpgradeRegex matches any Connection header value that includes upgrade + connectionUpgradeRegex = regexp.MustCompile("(^|.*,\\s*)upgrade($|\\s*,)") +) + +// IsWebSocketRequest returns true if the incoming request contains connection upgrade headers +// for WebSockets. +func IsWebSocketRequest(req *http.Request) bool { + if !strings.EqualFold(req.Header.Get("Upgrade"), "websocket") { + return false + } + return connectionUpgradeRegex.MatchString(strings.ToLower(req.Header.Get("Connection"))) +} + +// IgnoreReceives reads from a WebSocket until it is closed, then returns. If timeout is set, the +// read and write deadlines are pushed every time a new message is received. +func IgnoreReceives(ws *websocket.Conn, timeout time.Duration) { + defer runtime.HandleCrash() + var data []byte + for { + resetTimeout(ws, timeout) + if err := websocket.Message.Receive(ws, &data); err != nil { + return + } + } +} + +// handshake ensures the provided user protocol matches one of the allowed protocols. It returns +// no error if no protocol is specified. +func handshake(config *websocket.Config, req *http.Request, allowed []string) error { + protocols := config.Protocol + if len(protocols) == 0 { + protocols = []string{""} + } + + for _, protocol := range protocols { + for _, allow := range allowed { + if allow == protocol { + config.Protocol = []string{protocol} + return nil + } + } + } + + return fmt.Errorf("requested protocol(s) are not supported: %v; supports %v", config.Protocol, allowed) +} + +// ChannelProtocolConfig describes a websocket subprotocol with channels. +type ChannelProtocolConfig struct { + Binary bool + Channels []ChannelType +} + +// NewDefaultChannelProtocols returns a channel protocol map with the +// subprotocols "", "channel.k8s.io", "base64.channel.k8s.io" and the given +// channels. +func NewDefaultChannelProtocols(channels []ChannelType) map[string]ChannelProtocolConfig { + return map[string]ChannelProtocolConfig{ + "": {Binary: true, Channels: channels}, + ChannelWebSocketProtocol: {Binary: true, Channels: channels}, + Base64ChannelWebSocketProtocol: {Binary: false, Channels: channels}, + } +} + +// Conn supports sending multiple binary channels over a websocket connection. +type Conn struct { + protocols map[string]ChannelProtocolConfig + selectedProtocol string + channels []*websocketChannel + codec codecType + ready chan struct{} + ws *websocket.Conn + timeout time.Duration +} + +// NewConn creates a WebSocket connection that supports a set of channels. Channels begin each +// web socket message with a single byte indicating the channel number (0-N). 255 is reserved for +// future use. The channel types for each channel are passed as an array, supporting the different +// duplex modes. Read and Write refer to whether the channel can be used as a Reader or Writer. +// +// The protocols parameter maps subprotocol names to ChannelProtocols. The empty string subprotocol +// name is used if websocket.Config.Protocol is empty. +func NewConn(protocols map[string]ChannelProtocolConfig) *Conn { + return &Conn{ + ready: make(chan struct{}), + protocols: protocols, + } +} + +// SetIdleTimeout sets the interval for both reads and writes before timeout. If not specified, +// there is no timeout on the connection. +func (conn *Conn) SetIdleTimeout(duration time.Duration) { + conn.timeout = duration +} + +// Open the connection and create channels for reading and writing. It returns +// the selected subprotocol, a slice of channels and an error. +func (conn *Conn) Open(w http.ResponseWriter, req *http.Request) (string, []io.ReadWriteCloser, error) { + go func() { + defer runtime.HandleCrash() + defer conn.Close() + websocket.Server{Handshake: conn.handshake, Handler: conn.handle}.ServeHTTP(w, req) + }() + <-conn.ready + rwc := make([]io.ReadWriteCloser, len(conn.channels)) + for i := range conn.channels { + rwc[i] = conn.channels[i] + } + return conn.selectedProtocol, rwc, nil +} + +func (conn *Conn) initialize(ws *websocket.Conn) { + negotiated := ws.Config().Protocol + conn.selectedProtocol = negotiated[0] + p := conn.protocols[conn.selectedProtocol] + if p.Binary { + conn.codec = rawCodec + } else { + conn.codec = base64Codec + } + conn.ws = ws + conn.channels = make([]*websocketChannel, len(p.Channels)) + for i, t := range p.Channels { + switch t { + case ReadChannel: + conn.channels[i] = newWebsocketChannel(conn, byte(i), true, false) + case WriteChannel: + conn.channels[i] = newWebsocketChannel(conn, byte(i), false, true) + case ReadWriteChannel: + conn.channels[i] = newWebsocketChannel(conn, byte(i), true, true) + case IgnoreChannel: + conn.channels[i] = newWebsocketChannel(conn, byte(i), false, false) + } + } + + close(conn.ready) +} + +func (conn *Conn) handshake(config *websocket.Config, req *http.Request) error { + supportedProtocols := make([]string, 0, len(conn.protocols)) + for p := range conn.protocols { + supportedProtocols = append(supportedProtocols, p) + } + return handshake(config, req, supportedProtocols) +} + +func (conn *Conn) resetTimeout() { + if conn.timeout > 0 { + conn.ws.SetDeadline(time.Now().Add(conn.timeout)) + } +} + +// Close is only valid after Open has been called +func (conn *Conn) Close() error { + <-conn.ready + for _, s := range conn.channels { + s.Close() + } + conn.ws.Close() + return nil +} + +// handle implements a websocket handler. +func (conn *Conn) handle(ws *websocket.Conn) { + defer conn.Close() + conn.initialize(ws) + + for { + conn.resetTimeout() + var data []byte + if err := websocket.Message.Receive(ws, &data); err != nil { + if err != io.EOF { + klog.Errorf("Error on socket receive: %v", err) + } + break + } + if len(data) == 0 { + continue + } + channel := data[0] + if conn.codec == base64Codec { + channel = channel - '0' + } + data = data[1:] + if int(channel) >= len(conn.channels) { + klog.V(6).Infof("Frame is targeted for a reader %d that is not valid, possible protocol error", channel) + continue + } + if _, err := conn.channels[channel].DataFromSocket(data); err != nil { + klog.Errorf("Unable to write frame to %d: %v\n%s", channel, err, string(data)) + continue + } + } +} + +// write multiplexes the specified channel onto the websocket +func (conn *Conn) write(num byte, data []byte) (int, error) { + conn.resetTimeout() + switch conn.codec { + case rawCodec: + frame := make([]byte, len(data)+1) + frame[0] = num + copy(frame[1:], data) + if err := websocket.Message.Send(conn.ws, frame); err != nil { + return 0, err + } + case base64Codec: + frame := string('0'+num) + base64.StdEncoding.EncodeToString(data) + if err := websocket.Message.Send(conn.ws, frame); err != nil { + return 0, err + } + } + return len(data), nil +} + +// websocketChannel represents a channel in a connection +type websocketChannel struct { + conn *Conn + num byte + r io.Reader + w io.WriteCloser + + read, write bool +} + +// newWebsocketChannel creates a pipe for writing to a websocket. Do not write to this pipe +// prior to the connection being opened. It may be no, half, or full duplex depending on +// read and write. +func newWebsocketChannel(conn *Conn, num byte, read, write bool) *websocketChannel { + r, w := io.Pipe() + return &websocketChannel{conn, num, r, w, read, write} +} + +func (p *websocketChannel) Write(data []byte) (int, error) { + if !p.write { + return len(data), nil + } + return p.conn.write(p.num, data) +} + +// DataFromSocket is invoked by the connection receiver to move data from the connection +// into a specific channel. +func (p *websocketChannel) DataFromSocket(data []byte) (int, error) { + if !p.read { + return len(data), nil + } + + switch p.conn.codec { + case rawCodec: + return p.w.Write(data) + case base64Codec: + dst := make([]byte, len(data)) + n, err := base64.StdEncoding.Decode(dst, data) + if err != nil { + return 0, err + } + return p.w.Write(dst[:n]) + } + return 0, nil +} + +func (p *websocketChannel) Read(data []byte) (int, error) { + if !p.read { + return 0, io.EOF + } + return p.r.Read(data) +} + +func (p *websocketChannel) Close() error { + return p.w.Close() +} diff --git a/vendor/k8s.io/apiserver/pkg/util/wsstream/doc.go b/vendor/k8s.io/apiserver/pkg/util/wsstream/doc.go new file mode 100644 index 0000000000..694ce81d20 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/wsstream/doc.go @@ -0,0 +1,21 @@ +/* +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 wsstream contains utilities for streaming content over WebSockets. +// The Conn type allows callers to multiplex multiple read/write channels over +// a single websocket. The Reader type allows an io.Reader to be copied over +// a websocket channel as binary content. +package wsstream // import "k8s.io/apiserver/pkg/util/wsstream" diff --git a/vendor/k8s.io/apiserver/pkg/util/wsstream/stream.go b/vendor/k8s.io/apiserver/pkg/util/wsstream/stream.go new file mode 100644 index 0000000000..ba7e6a519a --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/wsstream/stream.go @@ -0,0 +1,177 @@ +/* +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 wsstream + +import ( + "encoding/base64" + "io" + "net/http" + "sync" + "time" + + "golang.org/x/net/websocket" + + "k8s.io/apimachinery/pkg/util/runtime" +) + +// The WebSocket subprotocol "binary.k8s.io" will only send messages to the +// client and ignore messages sent to the server. The received messages are +// the exact bytes written to the stream. Zero byte messages are possible. +const binaryWebSocketProtocol = "binary.k8s.io" + +// The WebSocket subprotocol "base64.binary.k8s.io" will only send messages to the +// client and ignore messages sent to the server. The received messages are +// a base64 version of the bytes written to the stream. Zero byte messages are +// possible. +const base64BinaryWebSocketProtocol = "base64.binary.k8s.io" + +// ReaderProtocolConfig describes a websocket subprotocol with one stream. +type ReaderProtocolConfig struct { + Binary bool +} + +// NewDefaultReaderProtocols returns a stream protocol map with the +// subprotocols "", "channel.k8s.io", "base64.channel.k8s.io". +func NewDefaultReaderProtocols() map[string]ReaderProtocolConfig { + return map[string]ReaderProtocolConfig{ + "": {Binary: true}, + binaryWebSocketProtocol: {Binary: true}, + base64BinaryWebSocketProtocol: {Binary: false}, + } +} + +// Reader supports returning an arbitrary byte stream over a websocket channel. +type Reader struct { + err chan error + r io.Reader + ping bool + timeout time.Duration + protocols map[string]ReaderProtocolConfig + selectedProtocol string + + handleCrash func(additionalHandlers ...func(interface{})) // overridable for testing +} + +// NewReader creates a WebSocket pipe that will copy the contents of r to a provided +// WebSocket connection. If ping is true, a zero length message will be sent to the client +// before the stream begins reading. +// +// The protocols parameter maps subprotocol names to StreamProtocols. The empty string +// subprotocol name is used if websocket.Config.Protocol is empty. +func NewReader(r io.Reader, ping bool, protocols map[string]ReaderProtocolConfig) *Reader { + return &Reader{ + r: r, + err: make(chan error), + ping: ping, + protocols: protocols, + handleCrash: runtime.HandleCrash, + } +} + +// SetIdleTimeout sets the interval for both reads and writes before timeout. If not specified, +// there is no timeout on the reader. +func (r *Reader) SetIdleTimeout(duration time.Duration) { + r.timeout = duration +} + +func (r *Reader) handshake(config *websocket.Config, req *http.Request) error { + supportedProtocols := make([]string, 0, len(r.protocols)) + for p := range r.protocols { + supportedProtocols = append(supportedProtocols, p) + } + return handshake(config, req, supportedProtocols) +} + +// Copy the reader to the response. The created WebSocket is closed after this +// method completes. +func (r *Reader) Copy(w http.ResponseWriter, req *http.Request) error { + go func() { + defer r.handleCrash() + websocket.Server{Handshake: r.handshake, Handler: r.handle}.ServeHTTP(w, req) + }() + return <-r.err +} + +// handle implements a WebSocket handler. +func (r *Reader) handle(ws *websocket.Conn) { + // Close the connection when the client requests it, or when we finish streaming, whichever happens first + closeConnOnce := &sync.Once{} + closeConn := func() { + closeConnOnce.Do(func() { + ws.Close() + }) + } + + negotiated := ws.Config().Protocol + r.selectedProtocol = negotiated[0] + defer close(r.err) + defer closeConn() + + go func() { + defer runtime.HandleCrash() + // This blocks until the connection is closed. + // Client should not send anything. + IgnoreReceives(ws, r.timeout) + // Once the client closes, we should also close + closeConn() + }() + + r.err <- messageCopy(ws, r.r, !r.protocols[r.selectedProtocol].Binary, r.ping, r.timeout) +} + +func resetTimeout(ws *websocket.Conn, timeout time.Duration) { + if timeout > 0 { + ws.SetDeadline(time.Now().Add(timeout)) + } +} + +func messageCopy(ws *websocket.Conn, r io.Reader, base64Encode, ping bool, timeout time.Duration) error { + buf := make([]byte, 2048) + if ping { + resetTimeout(ws, timeout) + if base64Encode { + if err := websocket.Message.Send(ws, ""); err != nil { + return err + } + } else { + if err := websocket.Message.Send(ws, []byte{}); err != nil { + return err + } + } + } + for { + resetTimeout(ws, timeout) + n, err := r.Read(buf) + if err != nil { + if err == io.EOF { + return nil + } + return err + } + if n > 0 { + if base64Encode { + if err := websocket.Message.Send(ws, base64.StdEncoding.EncodeToString(buf[:n])); err != nil { + return err + } + } else { + if err := websocket.Message.Send(ws, buf[:n]); err != nil { + return err + } + } + } + } +} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/audit/buffered/buffered.go b/vendor/k8s.io/apiserver/plugin/pkg/audit/buffered/buffered.go new file mode 100644 index 0000000000..07f263b2e3 --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/audit/buffered/buffered.go @@ -0,0 +1,290 @@ +/* +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 buffered + +import ( + "fmt" + "sync" + "time" + + "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/wait" + auditinternal "k8s.io/apiserver/pkg/apis/audit" + "k8s.io/apiserver/pkg/audit" + "k8s.io/client-go/util/flowcontrol" +) + +// PluginName is the name reported in error metrics. +const PluginName = "buffered" + +// BatchConfig represents batching delegate audit backend configuration. +type BatchConfig struct { + // BufferSize defines a size of the buffering queue. + BufferSize int + // MaxBatchSize defines maximum size of a batch. + MaxBatchSize int + // MaxBatchWait indicates the maximum interval between two batches. + MaxBatchWait time.Duration + + // ThrottleEnable defines whether throttling will be applied to the batching process. + ThrottleEnable bool + // ThrottleQPS defines the allowed rate of batches per second sent to the delegate backend. + ThrottleQPS float32 + // ThrottleBurst defines the maximum number of requests sent to the delegate backend at the same moment in case + // the capacity defined by ThrottleQPS was not utilized. + ThrottleBurst int + + // Whether the delegate backend should be called asynchronously. + AsyncDelegate bool +} + +type bufferedBackend struct { + // The delegate backend that actually exports events. + delegateBackend audit.Backend + + // Channel to buffer events before sending to the delegate backend. + buffer chan *auditinternal.Event + // Maximum number of events in a batch sent to the delegate backend. + maxBatchSize int + // Amount of time to wait after sending a batch to the delegate backend before sending another one. + // + // Receiving maxBatchSize events will always trigger sending a batch, regardless of the amount of time passed. + maxBatchWait time.Duration + + // Whether the delegate backend should be called asynchronously. + asyncDelegate bool + + // Channel to signal that the batching routine has processed all remaining events and exited. + // Once `shutdownCh` is closed no new events will be sent to the delegate backend. + shutdownCh chan struct{} + + // WaitGroup to control the concurrency of sending batches to the delegate backend. + // Worker routine calls Add before sending a batch and + // then spawns a routine that calls Done after batch was processed by the delegate backend. + // This WaitGroup is used to wait for all sending routines to finish before shutting down audit backend. + wg sync.WaitGroup + + // Limits the number of batches sent to the delegate backend per second. + throttle flowcontrol.RateLimiter +} + +var _ audit.Backend = &bufferedBackend{} + +// NewBackend returns a buffered audit backend that wraps delegate backend. +// Buffered backend automatically runs and shuts down the delegate backend. +func NewBackend(delegate audit.Backend, config BatchConfig) audit.Backend { + var throttle flowcontrol.RateLimiter + if config.ThrottleEnable { + throttle = flowcontrol.NewTokenBucketRateLimiter(config.ThrottleQPS, config.ThrottleBurst) + } + return &bufferedBackend{ + delegateBackend: delegate, + buffer: make(chan *auditinternal.Event, config.BufferSize), + maxBatchSize: config.MaxBatchSize, + maxBatchWait: config.MaxBatchWait, + asyncDelegate: config.AsyncDelegate, + shutdownCh: make(chan struct{}), + wg: sync.WaitGroup{}, + throttle: throttle, + } +} + +func (b *bufferedBackend) Run(stopCh <-chan struct{}) error { + go func() { + // Signal that the working routine has exited. + defer close(b.shutdownCh) + + b.processIncomingEvents(stopCh) + + // Handle the events that were received after the last buffer + // scraping and before this line. Since the buffer is closed, no new + // events will come through. + allEventsProcessed := false + timer := make(chan time.Time) + for !allEventsProcessed { + allEventsProcessed = func() bool { + // Recover from any panic in order to try to process all remaining events. + // Note, that in case of a panic, the return value will be false and + // the loop execution will continue. + defer runtime.HandleCrash() + + events := b.collectEvents(timer, wait.NeverStop) + b.processEvents(events) + return len(events) == 0 + }() + } + }() + return b.delegateBackend.Run(stopCh) +} + +// Shutdown blocks until stopCh passed to the Run method is closed and all +// events added prior to that moment are batched and sent to the delegate backend. +func (b *bufferedBackend) Shutdown() { + // Wait until the routine spawned in Run method exits. + <-b.shutdownCh + + // Wait until all sending routines exit. + // + // - When b.shutdownCh is closed, we know that the goroutine in Run has terminated. + // - This means that processIncomingEvents has terminated. + // - Which means that b.buffer is closed and cannot accept any new events anymore. + // - Because processEvents is called synchronously from the Run goroutine, the waitgroup has its final value. + // Hence wg.Wait will not miss any more outgoing batches. + b.wg.Wait() + + b.delegateBackend.Shutdown() +} + +// processIncomingEvents runs a loop that collects events from the buffer. When +// b.stopCh is closed, processIncomingEvents stops and closes the buffer. +func (b *bufferedBackend) processIncomingEvents(stopCh <-chan struct{}) { + defer close(b.buffer) + + var ( + maxWaitChan <-chan time.Time + maxWaitTimer *time.Timer + ) + // Only use max wait batching if batching is enabled. + if b.maxBatchSize > 1 { + maxWaitTimer = time.NewTimer(b.maxBatchWait) + maxWaitChan = maxWaitTimer.C + defer maxWaitTimer.Stop() + } + + for { + func() { + // Recover from any panics caused by this function so a panic in the + // goroutine can't bring down the main routine. + defer runtime.HandleCrash() + + if b.maxBatchSize > 1 { + maxWaitTimer.Reset(b.maxBatchWait) + } + b.processEvents(b.collectEvents(maxWaitChan, stopCh)) + }() + + select { + case <-stopCh: + return + default: + } + } +} + +// collectEvents attempts to collect some number of events in a batch. +// +// The following things can cause collectEvents to stop and return the list +// of events: +// +// - Maximum number of events for a batch. +// - Timer has passed. +// - Buffer channel is closed and empty. +// - stopCh is closed. +func (b *bufferedBackend) collectEvents(timer <-chan time.Time, stopCh <-chan struct{}) []*auditinternal.Event { + var events []*auditinternal.Event + +L: + for i := 0; i < b.maxBatchSize; i++ { + select { + case ev, ok := <-b.buffer: + // Buffer channel was closed and no new events will follow. + if !ok { + break L + } + events = append(events, ev) + case <-timer: + // Timer has expired. Send currently accumulated batch. + break L + case <-stopCh: + // Backend has been stopped. Send currently accumulated batch. + break L + } + } + + return events +} + +// processEvents process the batch events in a goroutine using delegateBackend's ProcessEvents. +func (b *bufferedBackend) processEvents(events []*auditinternal.Event) { + if len(events) == 0 { + return + } + + // TODO(audit): Should control the number of active goroutines + // if one goroutine takes 5 seconds to finish, the number of goroutines can be 5 * defaultBatchThrottleQPS + if b.throttle != nil { + b.throttle.Accept() + } + + if b.asyncDelegate { + b.wg.Add(1) + go func() { + defer b.wg.Done() + defer runtime.HandleCrash() + + // Execute the real processing in a goroutine to keep it from blocking. + // This lets the batching routine continue draining the queue immediately. + b.delegateBackend.ProcessEvents(events...) + }() + } else { + func() { + defer runtime.HandleCrash() + + // Execute the real processing in a goroutine to keep it from blocking. + // This lets the batching routine continue draining the queue immediately. + b.delegateBackend.ProcessEvents(events...) + }() + } +} + +func (b *bufferedBackend) ProcessEvents(ev ...*auditinternal.Event) bool { + // The following mechanism is in place to support the situation when audit + // events are still coming after the backend was stopped. + var sendErr error + var evIndex int + + // If the delegateBackend was shutdown and the buffer channel was closed, an + // attempt to add an event to it will result in panic that we should + // recover from. + defer func() { + if err := recover(); err != nil { + sendErr = fmt.Errorf("audit backend shut down") + } + if sendErr != nil { + audit.HandlePluginError(PluginName, sendErr, ev[evIndex:]...) + } + }() + + for i, e := range ev { + evIndex = i + // Per the audit.Backend interface these events are reused after being + // sent to the Sink. Deep copy and send the copy to the queue. + event := e.DeepCopy() + + select { + case b.buffer <- event: + default: + sendErr = fmt.Errorf("audit buffer queue blocked") + return true + } + } + return true +} + +func (b *bufferedBackend) String() string { + return fmt.Sprintf("%s<%s>", PluginName, b.delegateBackend) +} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/audit/buffered/doc.go b/vendor/k8s.io/apiserver/plugin/pkg/audit/buffered/doc.go new file mode 100644 index 0000000000..a82599e426 --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/audit/buffered/doc.go @@ -0,0 +1,19 @@ +/* +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 buffered provides an implementation for the audit.Backend interface +// that batches incoming audit events and sends batches to the delegate audit.Backend. +package buffered // import "k8s.io/apiserver/plugin/pkg/audit/buffered" diff --git a/vendor/k8s.io/apiserver/plugin/pkg/audit/log/backend.go b/vendor/k8s.io/apiserver/plugin/pkg/audit/log/backend.go new file mode 100644 index 0000000000..2ef2cc6ece --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/audit/log/backend.go @@ -0,0 +1,104 @@ +/* +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 log + +import ( + "fmt" + "io" + "strings" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + auditinternal "k8s.io/apiserver/pkg/apis/audit" + "k8s.io/apiserver/pkg/audit" +) + +const ( + // FormatLegacy saves event in 1-line text format. + FormatLegacy = "legacy" + // FormatJson saves event in structured json format. + FormatJson = "json" + + // PluginName is the name of this plugin, to be used in help and logs. + PluginName = "log" +) + +// AllowedFormats are the formats known by log backend. +var AllowedFormats = []string{ + FormatLegacy, + FormatJson, +} + +type backend struct { + out io.Writer + format string + encoder runtime.Encoder +} + +var _ audit.Backend = &backend{} + +func NewBackend(out io.Writer, format string, groupVersion schema.GroupVersion) audit.Backend { + return &backend{ + out: out, + format: format, + encoder: audit.Codecs.LegacyCodec(groupVersion), + } +} + +func (b *backend) ProcessEvents(events ...*auditinternal.Event) bool { + success := true + for _, ev := range events { + success = b.logEvent(ev) && success + } + return success +} + +func (b *backend) logEvent(ev *auditinternal.Event) bool { + line := "" + switch b.format { + case FormatLegacy: + line = audit.EventString(ev) + "\n" + case FormatJson: + bs, err := runtime.Encode(b.encoder, ev) + if err != nil { + audit.HandlePluginError(PluginName, err, ev) + return false + } + line = string(bs[:]) + default: + audit.HandlePluginError(PluginName, fmt.Errorf("log format %q is not in list of known formats (%s)", + b.format, strings.Join(AllowedFormats, ",")), ev) + return false + } + if _, err := fmt.Fprint(b.out, line); err != nil { + audit.HandlePluginError(PluginName, err, ev) + return false + } + return true +} + +func (b *backend) Run(stopCh <-chan struct{}) error { + return nil +} + +func (b *backend) Shutdown() { + // Nothing to do here. +} + +func (b *backend) String() string { + return PluginName +} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/audit/truncate/doc.go b/vendor/k8s.io/apiserver/plugin/pkg/audit/truncate/doc.go new file mode 100644 index 0000000000..9392ac3147 --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/audit/truncate/doc.go @@ -0,0 +1,19 @@ +/* +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 truncate provides an implementation for the audit.Backend interface +// that truncates audit events and sends them to the delegate audit.Backend. +package truncate // import "k8s.io/apiserver/plugin/pkg/audit/truncate" diff --git a/vendor/k8s.io/apiserver/plugin/pkg/audit/truncate/truncate.go b/vendor/k8s.io/apiserver/plugin/pkg/audit/truncate/truncate.go new file mode 100644 index 0000000000..42a40e3ebe --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/audit/truncate/truncate.go @@ -0,0 +1,165 @@ +/* +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 truncate + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + auditinternal "k8s.io/apiserver/pkg/apis/audit" + "k8s.io/apiserver/pkg/audit" +) + +const ( + // PluginName is the name reported in error metrics. + PluginName = "truncate" + + // annotationKey defines the name of the annotation used to indicate truncation. + annotationKey = "audit.k8s.io/truncated" + // annotationValue defines the value of the annotation used to indicate truncation. + annotationValue = "true" +) + +// Config represents truncating backend configuration. +type Config struct { + // MaxEventSize defines max allowed size of the event. If the event is larger, + // truncating will be performed. + MaxEventSize int64 + + // MaxBatchSize defined max allowed size of the batch of events, passed to the backend. + // If the total size of the batch is larger than this number, batch will be split. Actual + // size of the serialized request might be slightly higher, on the order of hundreds of bytes. + MaxBatchSize int64 +} + +type backend struct { + // The delegate backend that actually exports events. + delegateBackend audit.Backend + + // Configuration used for truncation. + c Config + + // Encoder used to calculate audit event sizes. + e runtime.Encoder +} + +var _ audit.Backend = &backend{} + +// NewBackend returns a new truncating backend, using configuration passed in the parameters. +// Truncate backend automatically runs and shut downs the delegate backend. +func NewBackend(delegateBackend audit.Backend, config Config, groupVersion schema.GroupVersion) audit.Backend { + return &backend{ + delegateBackend: delegateBackend, + c: config, + e: audit.Codecs.LegacyCodec(groupVersion), + } +} + +func (b *backend) ProcessEvents(events ...*auditinternal.Event) bool { + var errors []error + var impacted []*auditinternal.Event + var batch []*auditinternal.Event + var batchSize int64 + success := true + for _, event := range events { + size, err := b.calcSize(event) + // If event was correctly serialized, but the size is more than allowed + // and it makes sense to do trimming, i.e. there's a request and/or + // response present, try to strip away request and response. + if err == nil && size > b.c.MaxEventSize && event.Level.GreaterOrEqual(auditinternal.LevelRequest) { + event = truncate(event) + size, err = b.calcSize(event) + } + if err != nil { + errors = append(errors, err) + impacted = append(impacted, event) + continue + } + if size > b.c.MaxEventSize { + errors = append(errors, fmt.Errorf("event is too large even after truncating")) + impacted = append(impacted, event) + continue + } + + if len(batch) > 0 && batchSize+size > b.c.MaxBatchSize { + success = b.delegateBackend.ProcessEvents(batch...) && success + batch = []*auditinternal.Event{} + batchSize = 0 + } + + batchSize += size + batch = append(batch, event) + } + + if len(batch) > 0 { + success = b.delegateBackend.ProcessEvents(batch...) && success + } + + if len(impacted) > 0 { + audit.HandlePluginError(PluginName, utilerrors.NewAggregate(errors), impacted...) + } + return success +} + +// truncate removed request and response objects from the audit events, +// to try and keep at least metadata. +func truncate(e *auditinternal.Event) *auditinternal.Event { + // Make a shallow copy to avoid copying response/request objects. + newEvent := &auditinternal.Event{} + *newEvent = *e + + newEvent.RequestObject = nil + newEvent.ResponseObject = nil + + if newEvent.Annotations == nil { + newEvent.Annotations = make(map[string]string) + } + newEvent.Annotations[annotationKey] = annotationValue + + return newEvent +} + +func (b *backend) Run(stopCh <-chan struct{}) error { + return b.delegateBackend.Run(stopCh) +} + +func (b *backend) Shutdown() { + b.delegateBackend.Shutdown() +} + +func (b *backend) calcSize(e *auditinternal.Event) (int64, error) { + s := &sizer{} + if err := b.e.Encode(e, s); err != nil { + return 0, err + } + return s.Size, nil +} + +func (b *backend) String() string { + return fmt.Sprintf("%s<%s>", PluginName, b.delegateBackend) +} + +type sizer struct { + Size int64 +} + +func (s *sizer) Write(p []byte) (n int, err error) { + s.Size += int64(len(p)) + return len(p), nil +} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/audit/webhook/webhook.go b/vendor/k8s.io/apiserver/plugin/pkg/audit/webhook/webhook.go new file mode 100644 index 0000000000..6355df4038 --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/audit/webhook/webhook.go @@ -0,0 +1,146 @@ +/* +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 webhook implements the audit.Backend interface using HTTP webhooks. +package webhook + +import ( + "context" + "fmt" + "time" + + "go.opentelemetry.io/otel/attribute" + + "k8s.io/apimachinery/pkg/runtime/schema" + utilnet "k8s.io/apimachinery/pkg/util/net" + "k8s.io/apimachinery/pkg/util/wait" + auditinternal "k8s.io/apiserver/pkg/apis/audit" + "k8s.io/apiserver/pkg/apis/audit/install" + "k8s.io/apiserver/pkg/audit" + "k8s.io/apiserver/pkg/util/webhook" + "k8s.io/client-go/rest" + "k8s.io/component-base/tracing" +) + +const ( + // PluginName is the name of this plugin, to be used in help and logs. + PluginName = "webhook" + + // DefaultInitialBackoffDelay is the default amount of time to wait before + // retrying sending audit events through a webhook. + DefaultInitialBackoffDelay = 10 * time.Second +) + +func init() { + install.Install(audit.Scheme) +} + +// retryOnError enforces the webhook client to retry requests +// on error regardless of its nature. +// The default implementation considers a very limited set of +// 'retriable' errors, assuming correct use of HTTP codes by +// external webhooks. +// That may easily lead to dropped audit events. In fact, there is +// hardly any error that could be a justified reason NOT to retry +// sending audit events if there is even a slight chance that the +// receiving service gets back to normal at some point. +func retryOnError(err error) bool { + if err != nil { + return true + } + return false +} + +func loadWebhook(configFile string, groupVersion schema.GroupVersion, retryBackoff wait.Backoff, customDial utilnet.DialFunc) (*webhook.GenericWebhook, error) { + clientConfig, err := webhook.LoadKubeconfig(configFile, customDial) + if err != nil { + return nil, err + } + w, err := webhook.NewGenericWebhook(audit.Scheme, audit.Codecs, clientConfig, + []schema.GroupVersion{groupVersion}, retryBackoff) + if err != nil { + return nil, err + } + + w.ShouldRetry = retryOnError + return w, nil +} + +type backend struct { + w *webhook.GenericWebhook + name string +} + +// NewDynamicBackend returns an audit backend configured from a REST client that +// sends events over HTTP to an external service. +func NewDynamicBackend(rc *rest.RESTClient, retryBackoff wait.Backoff) audit.Backend { + return &backend{ + w: &webhook.GenericWebhook{ + RestClient: rc, + RetryBackoff: retryBackoff, + ShouldRetry: retryOnError, + }, + name: fmt.Sprintf("dynamic_%s", PluginName), + } +} + +// NewBackend returns an audit backend that sends events over HTTP to an external service. +func NewBackend(kubeConfigFile string, groupVersion schema.GroupVersion, retryBackoff wait.Backoff, customDial utilnet.DialFunc) (audit.Backend, error) { + w, err := loadWebhook(kubeConfigFile, groupVersion, retryBackoff, customDial) + if err != nil { + return nil, err + } + return &backend{w: w, name: PluginName}, nil +} + +func (b *backend) Run(stopCh <-chan struct{}) error { + return nil +} + +func (b *backend) Shutdown() { + // nothing to do here +} + +func (b *backend) ProcessEvents(ev ...*auditinternal.Event) bool { + if err := b.processEvents(ev...); err != nil { + audit.HandlePluginError(b.String(), err, ev...) + return false + } + return true +} + +func (b *backend) processEvents(ev ...*auditinternal.Event) error { + var list auditinternal.EventList + for _, e := range ev { + list.Items = append(list.Items, *e) + } + return b.w.WithExponentialBackoff(context.Background(), func() rest.Result { + ctx, span := tracing.Start(context.Background(), "Call Audit Events webhook", + attribute.String("name", b.name), + attribute.Int("event-count", len(list.Items)), + ) + // Only log audit webhook traces that exceed a 25ms per object limit plus a 50ms + // request overhead allowance. The high per object limit used here is primarily to + // allow enough time for the serialization/deserialization of audit events, which + // contain nested request and response objects plus additional event fields. + defer span.End(time.Duration(50+25*len(list.Items)) * time.Millisecond) + return b.w.RestClient.Post().Body(&list).Do(ctx) + }).Error() +} + +func (b *backend) String() string { + return b.name +} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/metrics.go b/vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/metrics.go new file mode 100644 index 0000000000..32e469e80d --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/metrics.go @@ -0,0 +1,35 @@ +/* +Copyright 2021 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 ( + "context" +) + +// AuthenticatorMetrics specifies a set of methods that are used to register various metrics +type AuthenticatorMetrics struct { + // RecordRequestTotal increments the total number of requests for webhooks + RecordRequestTotal func(ctx context.Context, code string) + + // RecordRequestLatency measures request latency in seconds for webhooks. Broken down by status code. + RecordRequestLatency func(ctx context.Context, code string, latency float64) +} + +type noopMetrics struct{} + +func (noopMetrics) RequestTotal(context.Context, string) {} +func (noopMetrics) RequestLatency(context.Context, string, float64) {} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go b/vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go new file mode 100644 index 0000000000..7d19b4b7ab --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go @@ -0,0 +1,327 @@ +/* +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 webhook implements the authenticator.Token interface using HTTP webhooks. +package webhook + +import ( + "context" + "errors" + "fmt" + "strconv" + "time" + + authenticationv1 "k8s.io/api/authentication/v1" + authenticationv1beta1 "k8s.io/api/authentication/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apiserver/pkg/authentication/authenticator" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/util/webhook" + "k8s.io/client-go/kubernetes/scheme" + authenticationv1client "k8s.io/client-go/kubernetes/typed/authentication/v1" + "k8s.io/client-go/rest" + "k8s.io/klog/v2" +) + +// DefaultRetryBackoff returns the default backoff parameters for webhook retry. +func DefaultRetryBackoff() *wait.Backoff { + backoff := webhook.DefaultRetryBackoffWithInitialDelay(500 * time.Millisecond) + return &backoff +} + +// Ensure WebhookTokenAuthenticator implements the authenticator.Token interface. +var _ authenticator.Token = (*WebhookTokenAuthenticator)(nil) + +type tokenReviewer interface { + Create(ctx context.Context, review *authenticationv1.TokenReview, _ metav1.CreateOptions) (*authenticationv1.TokenReview, int, error) +} + +type WebhookTokenAuthenticator struct { + tokenReview tokenReviewer + retryBackoff wait.Backoff + implicitAuds authenticator.Audiences + requestTimeout time.Duration + metrics AuthenticatorMetrics +} + +// 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 authenticationv1client.AuthenticationV1Interface, implicitAuds authenticator.Audiences, retryBackoff wait.Backoff, requestTimeout time.Duration, metrics AuthenticatorMetrics) (*WebhookTokenAuthenticator, error) { + tokenReviewClient := &tokenReviewV1Client{tokenReview.RESTClient()} + return newWithBackoff(tokenReviewClient, retryBackoff, implicitAuds, requestTimeout, metrics) +} + +// New creates a new WebhookTokenAuthenticator from the provided rest +// config. It is recommend to wrap this authenticator with the token cache +// authenticator implemented in +// k8s.io/apiserver/pkg/authentication/token/cache. +func New(config *rest.Config, version string, implicitAuds authenticator.Audiences, retryBackoff wait.Backoff) (*WebhookTokenAuthenticator, error) { + tokenReview, err := tokenReviewInterfaceFromConfig(config, version, retryBackoff) + if err != nil { + return nil, err + } + return newWithBackoff(tokenReview, retryBackoff, implicitAuds, time.Duration(0), AuthenticatorMetrics{ + RecordRequestTotal: noopMetrics{}.RequestTotal, + RecordRequestLatency: noopMetrics{}.RequestLatency, + }) +} + +// newWithBackoff allows tests to skip the sleep. +func newWithBackoff(tokenReview tokenReviewer, retryBackoff wait.Backoff, implicitAuds authenticator.Audiences, requestTimeout time.Duration, metrics AuthenticatorMetrics) (*WebhookTokenAuthenticator, error) { + return &WebhookTokenAuthenticator{ + tokenReview, + retryBackoff, + implicitAuds, + requestTimeout, + metrics, + }, nil +} + +// AuthenticateToken implements the authenticator.Token interface. +func (w *WebhookTokenAuthenticator) AuthenticateToken(ctx context.Context, token string) (*authenticator.Response, bool, error) { + // We take implicit audiences of the API server at WebhookTokenAuthenticator + // construction time. The outline of how we validate audience here is: + // + // * if the ctx is not audience limited, don't do any audience validation. + // * if ctx is audience-limited, add the audiences to the tokenreview spec + // * if the tokenreview returns with audiences in the status that intersect + // with the audiences in the ctx, copy into the response and return success + // * if the tokenreview returns without an audience in the status, ensure + // the ctx audiences intersect with the implicit audiences, and set the + // intersection in the response. + // * otherwise return unauthenticated. + wantAuds, checkAuds := authenticator.AudiencesFrom(ctx) + r := &authenticationv1.TokenReview{ + Spec: authenticationv1.TokenReviewSpec{ + Token: token, + Audiences: wantAuds, + }, + } + var ( + result *authenticationv1.TokenReview + auds authenticator.Audiences + cancel context.CancelFunc + ) + + // set a hard timeout if it was defined + // if the child has a shorter deadline then it will expire first, + // otherwise if the parent has a shorter deadline then the parent will expire and it will be propagate to the child + if w.requestTimeout > 0 { + ctx, cancel = context.WithTimeout(ctx, w.requestTimeout) + defer cancel() + } + + // WithExponentialBackoff will return tokenreview create error (tokenReviewErr) if any. + if err := webhook.WithExponentialBackoff(ctx, w.retryBackoff, func() error { + var tokenReviewErr error + var statusCode int + + start := time.Now() + result, statusCode, tokenReviewErr = w.tokenReview.Create(ctx, r, metav1.CreateOptions{}) + latency := time.Since(start) + + if statusCode != 0 { + w.metrics.RecordRequestTotal(ctx, strconv.Itoa(statusCode)) + w.metrics.RecordRequestLatency(ctx, strconv.Itoa(statusCode), latency.Seconds()) + return tokenReviewErr + } + + if tokenReviewErr != nil { + w.metrics.RecordRequestTotal(ctx, "") + w.metrics.RecordRequestLatency(ctx, "", latency.Seconds()) + } + return tokenReviewErr + }, webhook.DefaultShouldRetry); err != nil { + // An error here indicates bad configuration or an outage. Log for debugging. + klog.Errorf("Failed to make webhook authenticator request: %v", err) + return nil, false, err + } + + if checkAuds { + gotAuds := w.implicitAuds + if len(result.Status.Audiences) > 0 { + gotAuds = result.Status.Audiences + } + auds = wantAuds.Intersect(gotAuds) + if len(auds) == 0 { + return nil, false, nil + } + } + + r.Status = result.Status + if !r.Status.Authenticated { + var err error + if len(r.Status.Error) != 0 { + err = errors.New(r.Status.Error) + } + return nil, false, err + } + + var extra map[string][]string + if r.Status.User.Extra != nil { + extra = map[string][]string{} + for k, v := range r.Status.User.Extra { + extra[k] = v + } + } + + return &authenticator.Response{ + User: &user.DefaultInfo{ + Name: r.Status.User.Username, + UID: r.Status.User.UID, + Groups: r.Status.User.Groups, + Extra: extra, + }, + Audiences: auds, + }, true, nil +} + +// tokenReviewInterfaceFromConfig builds a client from the specified kubeconfig file, +// and returns a TokenReviewInterface that uses that client. Note that the client submits TokenReview +// requests to the exact path specified in the kubeconfig file, so arbitrary non-API servers can be targeted. +func tokenReviewInterfaceFromConfig(config *rest.Config, version string, retryBackoff wait.Backoff) (tokenReviewer, error) { + localScheme := runtime.NewScheme() + if err := scheme.AddToScheme(localScheme); err != nil { + return nil, err + } + + switch version { + case authenticationv1.SchemeGroupVersion.Version: + groupVersions := []schema.GroupVersion{authenticationv1.SchemeGroupVersion} + if err := localScheme.SetVersionPriority(groupVersions...); err != nil { + return nil, err + } + gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, config, groupVersions, retryBackoff) + if err != nil { + return nil, err + } + return &tokenReviewV1ClientGW{gw.RestClient}, nil + + case authenticationv1beta1.SchemeGroupVersion.Version: + groupVersions := []schema.GroupVersion{authenticationv1beta1.SchemeGroupVersion} + if err := localScheme.SetVersionPriority(groupVersions...); err != nil { + return nil, err + } + gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, config, groupVersions, retryBackoff) + if err != nil { + return nil, err + } + return &tokenReviewV1beta1ClientGW{gw.RestClient}, nil + + default: + return nil, fmt.Errorf( + "unsupported authentication webhook version %q, supported versions are %q, %q", + version, + authenticationv1.SchemeGroupVersion.Version, + authenticationv1beta1.SchemeGroupVersion.Version, + ) + } + +} + +type tokenReviewV1Client struct { + client rest.Interface +} + +// Create takes the representation of a tokenReview and creates it. Returns the server's representation of the tokenReview, HTTP status code and an error, if there is any. +func (c *tokenReviewV1Client) Create(ctx context.Context, tokenReview *authenticationv1.TokenReview, opts metav1.CreateOptions) (result *authenticationv1.TokenReview, statusCode int, err error) { + result = &authenticationv1.TokenReview{} + + restResult := c.client.Post(). + Resource("tokenreviews"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(tokenReview). + Do(ctx) + + restResult.StatusCode(&statusCode) + err = restResult.Into(result) + return +} + +// tokenReviewV1ClientGW used by the generic webhook, doesn't specify GVR. +type tokenReviewV1ClientGW struct { + client rest.Interface +} + +// Create takes the representation of a tokenReview and creates it. Returns the server's representation of the tokenReview, HTTP status code and an error, if there is any. +func (c *tokenReviewV1ClientGW) Create(ctx context.Context, tokenReview *authenticationv1.TokenReview, opts metav1.CreateOptions) (result *authenticationv1.TokenReview, statusCode int, err error) { + result = &authenticationv1.TokenReview{} + + restResult := c.client.Post(). + Body(tokenReview). + Do(ctx) + + restResult.StatusCode(&statusCode) + err = restResult.Into(result) + return +} + +// tokenReviewV1beta1ClientGW used by the generic webhook, doesn't specify GVR. +type tokenReviewV1beta1ClientGW struct { + client rest.Interface +} + +func (t *tokenReviewV1beta1ClientGW) Create(ctx context.Context, review *authenticationv1.TokenReview, _ metav1.CreateOptions) (*authenticationv1.TokenReview, int, error) { + var statusCode int + v1beta1Review := &authenticationv1beta1.TokenReview{Spec: v1SpecToV1beta1Spec(&review.Spec)} + v1beta1Result := &authenticationv1beta1.TokenReview{} + + restResult := t.client.Post().Body(v1beta1Review).Do(ctx) + restResult.StatusCode(&statusCode) + err := restResult.Into(v1beta1Result) + if err != nil { + return nil, statusCode, err + } + review.Status = v1beta1StatusToV1Status(&v1beta1Result.Status) + return review, statusCode, nil +} + +func v1SpecToV1beta1Spec(in *authenticationv1.TokenReviewSpec) authenticationv1beta1.TokenReviewSpec { + return authenticationv1beta1.TokenReviewSpec{ + Token: in.Token, + Audiences: in.Audiences, + } +} + +func v1beta1StatusToV1Status(in *authenticationv1beta1.TokenReviewStatus) authenticationv1.TokenReviewStatus { + return authenticationv1.TokenReviewStatus{ + Authenticated: in.Authenticated, + User: v1beta1UserToV1User(in.User), + Audiences: in.Audiences, + Error: in.Error, + } +} + +func v1beta1UserToV1User(u authenticationv1beta1.UserInfo) authenticationv1.UserInfo { + var extra map[string]authenticationv1.ExtraValue + if u.Extra != nil { + extra = make(map[string]authenticationv1.ExtraValue, len(u.Extra)) + for k, v := range u.Extra { + extra[k] = authenticationv1.ExtraValue(v) + } + } + return authenticationv1.UserInfo{ + Username: u.Username, + UID: u.UID, + Groups: u.Groups, + Extra: extra, + } +} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/gencerts.sh b/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/gencerts.sh new file mode 100644 index 0000000000..a66f8f381e --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/gencerts.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash + +# 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. + +set -e + +# gencerts.sh generates the certificates for the webhook authz plugin tests. +# +# It is not expected to be run often (there is no go generate rule), and mainly +# exists for documentation purposes. + +cat > server.conf << EOF +[req] +req_extensions = v3_req +distinguished_name = req_distinguished_name +[req_distinguished_name] +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth +subjectAltName = @alt_names +[alt_names] +IP.1 = 127.0.0.1 +EOF + +cat > client.conf << EOF +[req] +req_extensions = v3_req +distinguished_name = req_distinguished_name +[req_distinguished_name] +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth +EOF + +# Create a certificate authority +openssl genrsa -out caKey.pem 2048 +openssl req -x509 -new -nodes -key caKey.pem -days 100000 -out caCert.pem -subj "/CN=webhook_authz_ca" + +# Create a second certificate authority +openssl genrsa -out badCAKey.pem 2048 +openssl req -x509 -new -nodes -key badCAKey.pem -days 100000 -out badCACert.pem -subj "/CN=webhook_authz_ca" + +# Create a server certiticate +openssl genrsa -out serverKey.pem 2048 +openssl req -new -key serverKey.pem -out server.csr -subj "/CN=webhook_authz_server" -config server.conf +openssl x509 -req -in server.csr -CA caCert.pem -CAkey caKey.pem -CAcreateserial -out serverCert.pem -days 100000 -extensions v3_req -extfile server.conf + +# Create a client certiticate +openssl genrsa -out clientKey.pem 2048 +openssl req -new -key clientKey.pem -out client.csr -subj "/CN=webhook_authz_client" -config client.conf +openssl x509 -req -in client.csr -CA caCert.pem -CAkey caKey.pem -CAcreateserial -out clientCert.pem -days 100000 -extensions v3_req -extfile client.conf + +outfile=certs_test.go + +cat > $outfile << EOF +/* +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. +*/ + +// This file was generated using openssl by the gencerts.sh script +// and holds raw certificates for the webhook tests. + +package webhook +EOF + +for file in caKey caCert badCAKey badCACert serverKey serverCert clientKey clientCert; do + data=$(cat ${file}.pem) + echo "" >> $outfile + echo "var $file = []byte(\`$data\`)" >> $outfile +done + +# Clean up after we're done. +rm ./*.pem +rm ./*.csr +rm ./*.srl +rm ./*.conf diff --git a/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/metrics.go b/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/metrics.go new file mode 100644 index 0000000000..0912378b17 --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/metrics.go @@ -0,0 +1,35 @@ +/* +Copyright 2021 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 ( + "context" +) + +// AuthorizerMetrics specifies a set of methods that are used to register various metrics for the webhook authorizer +type AuthorizerMetrics struct { + // RecordRequestTotal increments the total number of requests for the webhook authorizer + RecordRequestTotal func(ctx context.Context, code string) + + // RecordRequestLatency measures request latency in seconds for webhooks. Broken down by status code. + RecordRequestLatency func(ctx context.Context, code string, latency float64) +} + +type noopMetrics struct{} + +func (noopMetrics) RecordRequestTotal(context.Context, string) {} +func (noopMetrics) RecordRequestLatency(context.Context, string, float64) {} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go b/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go new file mode 100644 index 0000000000..191b373185 --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go @@ -0,0 +1,436 @@ +/* +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 webhook implements the authorizer.Authorizer interface using HTTP webhooks. +package webhook + +import ( + "context" + "encoding/json" + "fmt" + "strconv" + "time" + + authorizationv1 "k8s.io/api/authorization/v1" + authorizationv1beta1 "k8s.io/api/authorization/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/cache" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/util/webhook" + "k8s.io/client-go/kubernetes/scheme" + authorizationv1client "k8s.io/client-go/kubernetes/typed/authorization/v1" + "k8s.io/client-go/rest" + "k8s.io/klog/v2" +) + +const ( + // The maximum length of requester-controlled attributes to allow caching. + maxControlledAttrCacheSize = 10000 +) + +// DefaultRetryBackoff returns the default backoff parameters for webhook retry. +func DefaultRetryBackoff() *wait.Backoff { + backoff := webhook.DefaultRetryBackoffWithInitialDelay(500 * time.Millisecond) + return &backoff +} + +// Ensure Webhook implements the authorizer.Authorizer interface. +var _ authorizer.Authorizer = (*WebhookAuthorizer)(nil) + +type subjectAccessReviewer interface { + Create(context.Context, *authorizationv1.SubjectAccessReview, metav1.CreateOptions) (*authorizationv1.SubjectAccessReview, int, error) +} + +type WebhookAuthorizer struct { + subjectAccessReview subjectAccessReviewer + responseCache *cache.LRUExpireCache + authorizedTTL time.Duration + unauthorizedTTL time.Duration + retryBackoff wait.Backoff + decisionOnError authorizer.Decision + metrics AuthorizerMetrics +} + +// NewFromInterface creates a WebhookAuthorizer using the given subjectAccessReview client +func NewFromInterface(subjectAccessReview authorizationv1client.AuthorizationV1Interface, authorizedTTL, unauthorizedTTL time.Duration, retryBackoff wait.Backoff, metrics AuthorizerMetrics) (*WebhookAuthorizer, error) { + return newWithBackoff(&subjectAccessReviewV1Client{subjectAccessReview.RESTClient()}, authorizedTTL, unauthorizedTTL, retryBackoff, metrics) +} + +// New creates a new WebhookAuthorizer from the provided kubeconfig file. +// The config's cluster field is used to refer to the remote service, user refers to the returned authorizer. +// +// # clusters refers to the remote service. +// clusters: +// - name: name-of-remote-authz-service +// cluster: +// certificate-authority: /path/to/ca.pem # CA for verifying the remote service. +// server: https://authz.example.com/authorize # URL of remote service to query. Must use 'https'. +// +// # users refers to the API server's webhook configuration. +// users: +// - name: name-of-api-server +// user: +// client-certificate: /path/to/cert.pem # cert for the webhook plugin to use +// client-key: /path/to/key.pem # key matching the cert +// +// For additional HTTP configuration, refer to the kubeconfig documentation +// https://kubernetes.io/docs/user-guide/kubeconfig-file/. +func New(config *rest.Config, version string, authorizedTTL, unauthorizedTTL time.Duration, retryBackoff wait.Backoff) (*WebhookAuthorizer, error) { + subjectAccessReview, err := subjectAccessReviewInterfaceFromConfig(config, version, retryBackoff) + if err != nil { + return nil, err + } + return newWithBackoff(subjectAccessReview, authorizedTTL, unauthorizedTTL, retryBackoff, AuthorizerMetrics{ + RecordRequestTotal: noopMetrics{}.RecordRequestTotal, + RecordRequestLatency: noopMetrics{}.RecordRequestLatency, + }) +} + +// newWithBackoff allows tests to skip the sleep. +func newWithBackoff(subjectAccessReview subjectAccessReviewer, authorizedTTL, unauthorizedTTL time.Duration, retryBackoff wait.Backoff, metrics AuthorizerMetrics) (*WebhookAuthorizer, error) { + return &WebhookAuthorizer{ + subjectAccessReview: subjectAccessReview, + responseCache: cache.NewLRUExpireCache(8192), + authorizedTTL: authorizedTTL, + unauthorizedTTL: unauthorizedTTL, + retryBackoff: retryBackoff, + decisionOnError: authorizer.DecisionNoOpinion, + metrics: metrics, + }, nil +} + +// Authorize makes a REST request to the remote service describing the attempted action as a JSON +// serialized api.authorization.v1beta1.SubjectAccessReview object. An example request body is +// provided below. +// +// { +// "apiVersion": "authorization.k8s.io/v1beta1", +// "kind": "SubjectAccessReview", +// "spec": { +// "resourceAttributes": { +// "namespace": "kittensandponies", +// "verb": "GET", +// "group": "group3", +// "resource": "pods" +// }, +// "user": "jane", +// "group": [ +// "group1", +// "group2" +// ] +// } +// } +// +// The remote service is expected to fill the SubjectAccessReviewStatus field to either allow or +// disallow access. A permissive response would return: +// +// { +// "apiVersion": "authorization.k8s.io/v1beta1", +// "kind": "SubjectAccessReview", +// "status": { +// "allowed": true +// } +// } +// +// To disallow access, the remote service would return: +// +// { +// "apiVersion": "authorization.k8s.io/v1beta1", +// "kind": "SubjectAccessReview", +// "status": { +// "allowed": false, +// "reason": "user does not have read access to the namespace" +// } +// } +// +// TODO(mikedanese): We should eventually support failing closed when we +// encounter an error. We are failing open now to preserve backwards compatible +// behavior. +func (w *WebhookAuthorizer) Authorize(ctx context.Context, attr authorizer.Attributes) (decision authorizer.Decision, reason string, err error) { + r := &authorizationv1.SubjectAccessReview{} + if user := attr.GetUser(); user != nil { + r.Spec = authorizationv1.SubjectAccessReviewSpec{ + User: user.GetName(), + UID: user.GetUID(), + Groups: user.GetGroups(), + Extra: convertToSARExtra(user.GetExtra()), + } + } + + if attr.IsResourceRequest() { + r.Spec.ResourceAttributes = &authorizationv1.ResourceAttributes{ + Namespace: attr.GetNamespace(), + Verb: attr.GetVerb(), + Group: attr.GetAPIGroup(), + Version: attr.GetAPIVersion(), + Resource: attr.GetResource(), + Subresource: attr.GetSubresource(), + Name: attr.GetName(), + } + } else { + r.Spec.NonResourceAttributes = &authorizationv1.NonResourceAttributes{ + Path: attr.GetPath(), + Verb: attr.GetVerb(), + } + } + key, err := json.Marshal(r.Spec) + if err != nil { + return w.decisionOnError, "", err + } + if entry, ok := w.responseCache.Get(string(key)); ok { + r.Status = entry.(authorizationv1.SubjectAccessReviewStatus) + } else { + var result *authorizationv1.SubjectAccessReview + // WithExponentialBackoff will return SAR create error (sarErr) if any. + if err := webhook.WithExponentialBackoff(ctx, w.retryBackoff, func() error { + var sarErr error + var statusCode int + + start := time.Now() + result, statusCode, sarErr = w.subjectAccessReview.Create(ctx, r, metav1.CreateOptions{}) + latency := time.Since(start) + + if statusCode != 0 { + w.metrics.RecordRequestTotal(ctx, strconv.Itoa(statusCode)) + w.metrics.RecordRequestLatency(ctx, strconv.Itoa(statusCode), latency.Seconds()) + return sarErr + } + + if sarErr != nil { + w.metrics.RecordRequestTotal(ctx, "") + w.metrics.RecordRequestLatency(ctx, "", latency.Seconds()) + } + + return sarErr + }, webhook.DefaultShouldRetry); err != nil { + klog.Errorf("Failed to make webhook authorizer request: %v", err) + return w.decisionOnError, "", err + } + + r.Status = result.Status + if shouldCache(attr) { + if r.Status.Allowed { + w.responseCache.Add(string(key), r.Status, w.authorizedTTL) + } else { + w.responseCache.Add(string(key), r.Status, w.unauthorizedTTL) + } + } + } + switch { + case r.Status.Denied && r.Status.Allowed: + return authorizer.DecisionDeny, r.Status.Reason, fmt.Errorf("webhook subject access review returned both allow and deny response") + case r.Status.Denied: + return authorizer.DecisionDeny, r.Status.Reason, nil + case r.Status.Allowed: + return authorizer.DecisionAllow, r.Status.Reason, nil + default: + return authorizer.DecisionNoOpinion, r.Status.Reason, nil + } + +} + +// TODO: need to finish the method to get the rules when using webhook mode +func (w *WebhookAuthorizer) RulesFor(user user.Info, namespace string) ([]authorizer.ResourceRuleInfo, []authorizer.NonResourceRuleInfo, bool, error) { + var ( + resourceRules []authorizer.ResourceRuleInfo + nonResourceRules []authorizer.NonResourceRuleInfo + ) + incomplete := true + return resourceRules, nonResourceRules, incomplete, fmt.Errorf("webhook authorizer does not support user rule resolution") +} + +func convertToSARExtra(extra map[string][]string) map[string]authorizationv1.ExtraValue { + if extra == nil { + return nil + } + ret := map[string]authorizationv1.ExtraValue{} + for k, v := range extra { + ret[k] = authorizationv1.ExtraValue(v) + } + + return ret +} + +// subjectAccessReviewInterfaceFromConfig builds a client from the specified kubeconfig file, +// and returns a SubjectAccessReviewInterface that uses that client. Note that the client submits SubjectAccessReview +// requests to the exact path specified in the kubeconfig file, so arbitrary non-API servers can be targeted. +func subjectAccessReviewInterfaceFromConfig(config *rest.Config, version string, retryBackoff wait.Backoff) (subjectAccessReviewer, error) { + localScheme := runtime.NewScheme() + if err := scheme.AddToScheme(localScheme); err != nil { + return nil, err + } + + switch version { + case authorizationv1.SchemeGroupVersion.Version: + groupVersions := []schema.GroupVersion{authorizationv1.SchemeGroupVersion} + if err := localScheme.SetVersionPriority(groupVersions...); err != nil { + return nil, err + } + gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, config, groupVersions, retryBackoff) + if err != nil { + return nil, err + } + return &subjectAccessReviewV1ClientGW{gw.RestClient}, nil + + case authorizationv1beta1.SchemeGroupVersion.Version: + groupVersions := []schema.GroupVersion{authorizationv1beta1.SchemeGroupVersion} + if err := localScheme.SetVersionPriority(groupVersions...); err != nil { + return nil, err + } + gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, config, groupVersions, retryBackoff) + if err != nil { + return nil, err + } + return &subjectAccessReviewV1beta1ClientGW{gw.RestClient}, nil + + default: + return nil, fmt.Errorf( + "unsupported webhook authorizer version %q, supported versions are %q, %q", + version, + authorizationv1.SchemeGroupVersion.Version, + authorizationv1beta1.SchemeGroupVersion.Version, + ) + } +} + +type subjectAccessReviewV1Client struct { + client rest.Interface +} + +func (t *subjectAccessReviewV1Client) Create(ctx context.Context, subjectAccessReview *authorizationv1.SubjectAccessReview, opts metav1.CreateOptions) (result *authorizationv1.SubjectAccessReview, statusCode int, err error) { + result = &authorizationv1.SubjectAccessReview{} + + restResult := t.client.Post(). + Resource("subjectaccessreviews"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(subjectAccessReview). + Do(ctx) + + restResult.StatusCode(&statusCode) + err = restResult.Into(result) + return +} + +// subjectAccessReviewV1ClientGW used by the generic webhook, doesn't specify GVR. +type subjectAccessReviewV1ClientGW struct { + client rest.Interface +} + +func (t *subjectAccessReviewV1ClientGW) Create(ctx context.Context, subjectAccessReview *authorizationv1.SubjectAccessReview, _ metav1.CreateOptions) (*authorizationv1.SubjectAccessReview, int, error) { + var statusCode int + result := &authorizationv1.SubjectAccessReview{} + + restResult := t.client.Post().Body(subjectAccessReview).Do(ctx) + + restResult.StatusCode(&statusCode) + err := restResult.Into(result) + + return result, statusCode, err +} + +// subjectAccessReviewV1beta1ClientGW used by the generic webhook, doesn't specify GVR. +type subjectAccessReviewV1beta1ClientGW struct { + client rest.Interface +} + +func (t *subjectAccessReviewV1beta1ClientGW) Create(ctx context.Context, subjectAccessReview *authorizationv1.SubjectAccessReview, _ metav1.CreateOptions) (*authorizationv1.SubjectAccessReview, int, error) { + var statusCode int + v1beta1Review := &authorizationv1beta1.SubjectAccessReview{Spec: v1SpecToV1beta1Spec(&subjectAccessReview.Spec)} + v1beta1Result := &authorizationv1beta1.SubjectAccessReview{} + + restResult := t.client.Post().Body(v1beta1Review).Do(ctx) + + restResult.StatusCode(&statusCode) + err := restResult.Into(v1beta1Result) + if err == nil { + subjectAccessReview.Status = v1beta1StatusToV1Status(&v1beta1Result.Status) + } + return subjectAccessReview, statusCode, err +} + +// shouldCache determines whether it is safe to cache the given request attributes. If the +// requester-controlled attributes are too large, this may be a DoS attempt, so we skip the cache. +func shouldCache(attr authorizer.Attributes) bool { + controlledAttrSize := int64(len(attr.GetNamespace())) + + int64(len(attr.GetVerb())) + + int64(len(attr.GetAPIGroup())) + + int64(len(attr.GetAPIVersion())) + + int64(len(attr.GetResource())) + + int64(len(attr.GetSubresource())) + + int64(len(attr.GetName())) + + int64(len(attr.GetPath())) + return controlledAttrSize < maxControlledAttrCacheSize +} + +func v1beta1StatusToV1Status(in *authorizationv1beta1.SubjectAccessReviewStatus) authorizationv1.SubjectAccessReviewStatus { + return authorizationv1.SubjectAccessReviewStatus{ + Allowed: in.Allowed, + Denied: in.Denied, + Reason: in.Reason, + EvaluationError: in.EvaluationError, + } +} + +func v1SpecToV1beta1Spec(in *authorizationv1.SubjectAccessReviewSpec) authorizationv1beta1.SubjectAccessReviewSpec { + return authorizationv1beta1.SubjectAccessReviewSpec{ + ResourceAttributes: v1ResourceAttributesToV1beta1ResourceAttributes(in.ResourceAttributes), + NonResourceAttributes: v1NonResourceAttributesToV1beta1NonResourceAttributes(in.NonResourceAttributes), + User: in.User, + Groups: in.Groups, + Extra: v1ExtraToV1beta1Extra(in.Extra), + UID: in.UID, + } +} + +func v1ResourceAttributesToV1beta1ResourceAttributes(in *authorizationv1.ResourceAttributes) *authorizationv1beta1.ResourceAttributes { + if in == nil { + return nil + } + return &authorizationv1beta1.ResourceAttributes{ + Namespace: in.Namespace, + Verb: in.Verb, + Group: in.Group, + Version: in.Version, + Resource: in.Resource, + Subresource: in.Subresource, + Name: in.Name, + } +} + +func v1NonResourceAttributesToV1beta1NonResourceAttributes(in *authorizationv1.NonResourceAttributes) *authorizationv1beta1.NonResourceAttributes { + if in == nil { + return nil + } + return &authorizationv1beta1.NonResourceAttributes{ + Path: in.Path, + Verb: in.Verb, + } +} + +func v1ExtraToV1beta1Extra(in map[string]authorizationv1.ExtraValue) map[string]authorizationv1beta1.ExtraValue { + if in == nil { + return nil + } + ret := make(map[string]authorizationv1beta1.ExtraValue, len(in)) + for k, v := range in { + ret[k] = authorizationv1beta1.ExtraValue(v) + } + return ret +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchcondition.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchcondition.go new file mode 100644 index 0000000000..ea1dc377b9 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchcondition.go @@ -0,0 +1,48 @@ +/* +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 applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// MatchConditionApplyConfiguration represents an declarative configuration of the MatchCondition type for use +// with apply. +type MatchConditionApplyConfiguration struct { + Name *string `json:"name,omitempty"` + Expression *string `json:"expression,omitempty"` +} + +// MatchConditionApplyConfiguration constructs an declarative configuration of the MatchCondition type for use with +// apply. +func MatchCondition() *MatchConditionApplyConfiguration { + return &MatchConditionApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithName(value string) *MatchConditionApplyConfiguration { + b.Name = &value + return b +} + +// WithExpression sets the Expression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Expression field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithExpression(value string) *MatchConditionApplyConfiguration { + b.Expression = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go index eba37bafdb..faff51a041 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go @@ -37,6 +37,7 @@ type MutatingWebhookApplyConfiguration struct { TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty"` ReinvocationPolicy *admissionregistrationv1.ReinvocationPolicyType `json:"reinvocationPolicy,omitempty"` + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` } // MutatingWebhookApplyConfiguration constructs an declarative configuration of the MutatingWebhook type for use with @@ -139,3 +140,16 @@ func (b *MutatingWebhookApplyConfiguration) WithReinvocationPolicy(value admissi b.ReinvocationPolicy = &value return b } + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *MutatingWebhookApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *MutatingWebhookApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go index d0691de107..613856bac7 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go @@ -36,6 +36,7 @@ type ValidatingWebhookApplyConfiguration struct { SideEffects *admissionregistrationv1.SideEffectClass `json:"sideEffects,omitempty"` TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty"` + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` } // ValidatingWebhookApplyConfiguration constructs an declarative configuration of the ValidatingWebhook type for use with @@ -130,3 +131,16 @@ func (b *ValidatingWebhookApplyConfiguration) WithAdmissionReviewVersions(values } return b } + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *ValidatingWebhookApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *ValidatingWebhookApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/admissionpolicyspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/admissionpolicyspec.go deleted file mode 100644 index 4936110fbd..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/admissionpolicyspec.go +++ /dev/null @@ -1,75 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" -) - -// AdmissionPolicySpecApplyConfiguration represents an declarative configuration of the AdmissionPolicySpec type for use -// with apply. -type AdmissionPolicySpecApplyConfiguration struct { - ParamSource *ParamSourceApplyConfiguration `json:"paramSource,omitempty"` - MatchResources *MatchResourcesApplyConfiguration `json:"matchResources,omitempty"` - Validations []ValidationApplyConfiguration `json:"validations,omitempty"` - FailurePolicy *admissionregistrationv1alpha1.FailurePolicyType `json:"failurePolicy,omitempty"` -} - -// AdmissionPolicySpecApplyConfiguration constructs an declarative configuration of the AdmissionPolicySpec type for use with -// apply. -func AdmissionPolicySpec() *AdmissionPolicySpecApplyConfiguration { - return &AdmissionPolicySpecApplyConfiguration{} -} - -// WithParamSource sets the ParamSource field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ParamSource field is set to the value of the last call. -func (b *AdmissionPolicySpecApplyConfiguration) WithParamSource(value *ParamSourceApplyConfiguration) *AdmissionPolicySpecApplyConfiguration { - b.ParamSource = value - return b -} - -// WithMatchResources sets the MatchResources field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the MatchResources field is set to the value of the last call. -func (b *AdmissionPolicySpecApplyConfiguration) WithMatchResources(value *MatchResourcesApplyConfiguration) *AdmissionPolicySpecApplyConfiguration { - b.MatchResources = value - return b -} - -// WithValidations adds the given value to the Validations field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Validations field. -func (b *AdmissionPolicySpecApplyConfiguration) WithValidations(values ...*ValidationApplyConfiguration) *AdmissionPolicySpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithValidations") - } - b.Validations = append(b.Validations, *values[i]) - } - return b -} - -// WithFailurePolicy sets the FailurePolicy field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the FailurePolicy field is set to the value of the last call. -func (b *AdmissionPolicySpecApplyConfiguration) WithFailurePolicy(value admissionregistrationv1alpha1.FailurePolicyType) *AdmissionPolicySpecApplyConfiguration { - b.FailurePolicy = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/auditannotation.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/auditannotation.go new file mode 100644 index 0000000000..023695139d --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/auditannotation.go @@ -0,0 +1,48 @@ +/* +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 applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// AuditAnnotationApplyConfiguration represents an declarative configuration of the AuditAnnotation type for use +// with apply. +type AuditAnnotationApplyConfiguration struct { + Key *string `json:"key,omitempty"` + ValueExpression *string `json:"valueExpression,omitempty"` +} + +// AuditAnnotationApplyConfiguration constructs an declarative configuration of the AuditAnnotation type for use with +// apply. +func AuditAnnotation() *AuditAnnotationApplyConfiguration { + return &AuditAnnotationApplyConfiguration{} +} + +// WithKey sets the Key field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Key field is set to the value of the last call. +func (b *AuditAnnotationApplyConfiguration) WithKey(value string) *AuditAnnotationApplyConfiguration { + b.Key = &value + return b +} + +// WithValueExpression sets the ValueExpression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ValueExpression field is set to the value of the last call. +func (b *AuditAnnotationApplyConfiguration) WithValueExpression(value string) *AuditAnnotationApplyConfiguration { + b.ValueExpression = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/expressionwarning.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/expressionwarning.go new file mode 100644 index 0000000000..f8b511f512 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/expressionwarning.go @@ -0,0 +1,48 @@ +/* +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 applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// ExpressionWarningApplyConfiguration represents an declarative configuration of the ExpressionWarning type for use +// with apply. +type ExpressionWarningApplyConfiguration struct { + FieldRef *string `json:"fieldRef,omitempty"` + Warning *string `json:"warning,omitempty"` +} + +// ExpressionWarningApplyConfiguration constructs an declarative configuration of the ExpressionWarning type for use with +// apply. +func ExpressionWarning() *ExpressionWarningApplyConfiguration { + return &ExpressionWarningApplyConfiguration{} +} + +// WithFieldRef sets the FieldRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the FieldRef field is set to the value of the last call. +func (b *ExpressionWarningApplyConfiguration) WithFieldRef(value string) *ExpressionWarningApplyConfiguration { + b.FieldRef = &value + return b +} + +// WithWarning sets the Warning field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Warning field is set to the value of the last call. +func (b *ExpressionWarningApplyConfiguration) WithWarning(value string) *ExpressionWarningApplyConfiguration { + b.Warning = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramsource.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchcondition.go similarity index 50% rename from vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramsource.go rename to vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchcondition.go index a7a5a6af83..186c750f96 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramsource.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchcondition.go @@ -18,31 +18,31 @@ limitations under the License. package v1alpha1 -// ParamSourceApplyConfiguration represents an declarative configuration of the ParamSource type for use +// MatchConditionApplyConfiguration represents an declarative configuration of the MatchCondition type for use // with apply. -type ParamSourceApplyConfiguration struct { - APIVersion *string `json:"apiVersion,omitempty"` - Kind *string `json:"kind,omitempty"` +type MatchConditionApplyConfiguration struct { + Name *string `json:"name,omitempty"` + Expression *string `json:"expression,omitempty"` } -// ParamSourceApplyConfiguration constructs an declarative configuration of the ParamSource type for use with +// MatchConditionApplyConfiguration constructs an declarative configuration of the MatchCondition type for use with // apply. -func ParamSource() *ParamSourceApplyConfiguration { - return &ParamSourceApplyConfiguration{} +func MatchCondition() *MatchConditionApplyConfiguration { + return &MatchConditionApplyConfiguration{} } -// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// WithName sets the Name field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the APIVersion field is set to the value of the last call. -func (b *ParamSourceApplyConfiguration) WithAPIVersion(value string) *ParamSourceApplyConfiguration { - b.APIVersion = &value +// If called multiple times, the Name field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithName(value string) *MatchConditionApplyConfiguration { + b.Name = &value return b } -// WithKind sets the Kind field in the declarative configuration to the given value +// WithExpression sets the Expression field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Kind field is set to the value of the last call. -func (b *ParamSourceApplyConfiguration) WithKind(value string) *ParamSourceApplyConfiguration { - b.Kind = &value +// If called multiple times, the Expression field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithExpression(value string) *MatchConditionApplyConfiguration { + b.Expression = &value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/rule.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/rule.go deleted file mode 100644 index 313de9d5f5..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/rule.go +++ /dev/null @@ -1,76 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1alpha1 "k8s.io/api/admissionregistration/v1alpha1" -) - -// RuleApplyConfiguration represents an declarative configuration of the Rule type for use -// with apply. -type RuleApplyConfiguration struct { - APIGroups []string `json:"apiGroups,omitempty"` - APIVersions []string `json:"apiVersions,omitempty"` - Resources []string `json:"resources,omitempty"` - Scope *v1alpha1.ScopeType `json:"scope,omitempty"` -} - -// RuleApplyConfiguration constructs an declarative configuration of the Rule type for use with -// apply. -func Rule() *RuleApplyConfiguration { - return &RuleApplyConfiguration{} -} - -// WithAPIGroups adds the given value to the APIGroups field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIGroups field. -func (b *RuleApplyConfiguration) WithAPIGroups(values ...string) *RuleApplyConfiguration { - for i := range values { - b.APIGroups = append(b.APIGroups, values[i]) - } - return b -} - -// WithAPIVersions adds the given value to the APIVersions field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIVersions field. -func (b *RuleApplyConfiguration) WithAPIVersions(values ...string) *RuleApplyConfiguration { - for i := range values { - b.APIVersions = append(b.APIVersions, values[i]) - } - return b -} - -// WithResources adds the given value to the Resources field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Resources field. -func (b *RuleApplyConfiguration) WithResources(values ...string) *RuleApplyConfiguration { - for i := range values { - b.Resources = append(b.Resources, values[i]) - } - return b -} - -// WithScope sets the Scope field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Scope field is set to the value of the last call. -func (b *RuleApplyConfiguration) WithScope(value v1alpha1.ScopeType) *RuleApplyConfiguration { - b.Scope = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/rulewithoperations.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/rulewithoperations.go deleted file mode 100644 index 112f4826b6..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/rulewithoperations.go +++ /dev/null @@ -1,85 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1 "k8s.io/api/admissionregistration/v1" - admissionregistrationv1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1" -) - -// RuleWithOperationsApplyConfiguration represents an declarative configuration of the RuleWithOperations type for use -// with apply. -type RuleWithOperationsApplyConfiguration struct { - Operations []v1.OperationType `json:"operations,omitempty"` - admissionregistrationv1.RuleApplyConfiguration `json:",inline"` -} - -// RuleWithOperationsApplyConfiguration constructs an declarative configuration of the RuleWithOperations type for use with -// apply. -func RuleWithOperations() *RuleWithOperationsApplyConfiguration { - return &RuleWithOperationsApplyConfiguration{} -} - -// WithOperations adds the given value to the Operations field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Operations field. -func (b *RuleWithOperationsApplyConfiguration) WithOperations(values ...v1.OperationType) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.Operations = append(b.Operations, values[i]) - } - return b -} - -// WithAPIGroups adds the given value to the APIGroups field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIGroups field. -func (b *RuleWithOperationsApplyConfiguration) WithAPIGroups(values ...string) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.APIGroups = append(b.APIGroups, values[i]) - } - return b -} - -// WithAPIVersions adds the given value to the APIVersions field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIVersions field. -func (b *RuleWithOperationsApplyConfiguration) WithAPIVersions(values ...string) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.APIVersions = append(b.APIVersions, values[i]) - } - return b -} - -// WithResources adds the given value to the Resources field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Resources field. -func (b *RuleWithOperationsApplyConfiguration) WithResources(values ...string) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.Resources = append(b.Resources, values[i]) - } - return b -} - -// WithScope sets the Scope field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Scope field is set to the value of the last call. -func (b *RuleWithOperationsApplyConfiguration) WithScope(value v1.ScopeType) *RuleWithOperationsApplyConfiguration { - b.Scope = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/typechecking.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/typechecking.go new file mode 100644 index 0000000000..42a9170710 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/typechecking.go @@ -0,0 +1,44 @@ +/* +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 applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// TypeCheckingApplyConfiguration represents an declarative configuration of the TypeChecking type for use +// with apply. +type TypeCheckingApplyConfiguration struct { + ExpressionWarnings []ExpressionWarningApplyConfiguration `json:"expressionWarnings,omitempty"` +} + +// TypeCheckingApplyConfiguration constructs an declarative configuration of the TypeChecking type for use with +// apply. +func TypeChecking() *TypeCheckingApplyConfiguration { + return &TypeCheckingApplyConfiguration{} +} + +// WithExpressionWarnings adds the given value to the ExpressionWarnings field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ExpressionWarnings field. +func (b *TypeCheckingApplyConfiguration) WithExpressionWarnings(values ...*ExpressionWarningApplyConfiguration) *TypeCheckingApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithExpressionWarnings") + } + b.ExpressionWarnings = append(b.ExpressionWarnings, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicy.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicy.go index 3a23e0c726..c860b85cf7 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicy.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicy.go @@ -32,7 +32,8 @@ import ( type ValidatingAdmissionPolicyApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *ValidatingAdmissionPolicySpecApplyConfiguration `json:"spec,omitempty"` + Spec *ValidatingAdmissionPolicySpecApplyConfiguration `json:"spec,omitempty"` + Status *ValidatingAdmissionPolicyStatusApplyConfiguration `json:"status,omitempty"` } // ValidatingAdmissionPolicy constructs an declarative configuration of the ValidatingAdmissionPolicy type for use with @@ -245,3 +246,11 @@ func (b *ValidatingAdmissionPolicyApplyConfiguration) WithSpec(value *Validating b.Spec = value return b } + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithStatus(value *ValidatingAdmissionPolicyStatusApplyConfiguration) *ValidatingAdmissionPolicyApplyConfiguration { + b.Status = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybindingspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybindingspec.go index f06f655493..c9a4ff7ab4 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybindingspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybindingspec.go @@ -18,12 +18,17 @@ limitations under the License. package v1alpha1 +import ( + admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" +) + // ValidatingAdmissionPolicyBindingSpecApplyConfiguration represents an declarative configuration of the ValidatingAdmissionPolicyBindingSpec type for use // with apply. type ValidatingAdmissionPolicyBindingSpecApplyConfiguration struct { - PolicyName *string `json:"policyName,omitempty"` - ParamRef *ParamRefApplyConfiguration `json:"paramRef,omitempty"` - MatchResources *MatchResourcesApplyConfiguration `json:"matchResources,omitempty"` + PolicyName *string `json:"policyName,omitempty"` + ParamRef *ParamRefApplyConfiguration `json:"paramRef,omitempty"` + MatchResources *MatchResourcesApplyConfiguration `json:"matchResources,omitempty"` + ValidationActions []admissionregistrationv1alpha1.ValidationAction `json:"validationActions,omitempty"` } // ValidatingAdmissionPolicyBindingSpecApplyConfiguration constructs an declarative configuration of the ValidatingAdmissionPolicyBindingSpec type for use with @@ -55,3 +60,13 @@ func (b *ValidatingAdmissionPolicyBindingSpecApplyConfiguration) WithMatchResour b.MatchResources = value return b } + +// WithValidationActions adds the given value to the ValidationActions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ValidationActions field. +func (b *ValidatingAdmissionPolicyBindingSpecApplyConfiguration) WithValidationActions(values ...admissionregistrationv1alpha1.ValidationAction) *ValidatingAdmissionPolicyBindingSpecApplyConfiguration { + for i := range values { + b.ValidationActions = append(b.ValidationActions, values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicyspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicyspec.go index cba1e720ce..f674b5b1ec 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicyspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicyspec.go @@ -29,6 +29,8 @@ type ValidatingAdmissionPolicySpecApplyConfiguration struct { MatchConstraints *MatchResourcesApplyConfiguration `json:"matchConstraints,omitempty"` Validations []ValidationApplyConfiguration `json:"validations,omitempty"` FailurePolicy *admissionregistrationv1alpha1.FailurePolicyType `json:"failurePolicy,omitempty"` + AuditAnnotations []AuditAnnotationApplyConfiguration `json:"auditAnnotations,omitempty"` + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` } // ValidatingAdmissionPolicySpecApplyConfiguration constructs an declarative configuration of the ValidatingAdmissionPolicySpec type for use with @@ -73,3 +75,29 @@ func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithFailurePolicy(valu b.FailurePolicy = &value return b } + +// WithAuditAnnotations adds the given value to the AuditAnnotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the AuditAnnotations field. +func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithAuditAnnotations(values ...*AuditAnnotationApplyConfiguration) *ValidatingAdmissionPolicySpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithAuditAnnotations") + } + b.AuditAnnotations = append(b.AuditAnnotations, *values[i]) + } + return b +} + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *ValidatingAdmissionPolicySpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicystatus.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicystatus.go new file mode 100644 index 0000000000..821184c8a8 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicystatus.go @@ -0,0 +1,66 @@ +/* +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 applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ValidatingAdmissionPolicyStatusApplyConfiguration represents an declarative configuration of the ValidatingAdmissionPolicyStatus type for use +// with apply. +type ValidatingAdmissionPolicyStatusApplyConfiguration struct { + ObservedGeneration *int64 `json:"observedGeneration,omitempty"` + TypeChecking *TypeCheckingApplyConfiguration `json:"typeChecking,omitempty"` + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// ValidatingAdmissionPolicyStatusApplyConfiguration constructs an declarative configuration of the ValidatingAdmissionPolicyStatus type for use with +// apply. +func ValidatingAdmissionPolicyStatus() *ValidatingAdmissionPolicyStatusApplyConfiguration { + return &ValidatingAdmissionPolicyStatusApplyConfiguration{} +} + +// WithObservedGeneration sets the ObservedGeneration field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ObservedGeneration field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyStatusApplyConfiguration) WithObservedGeneration(value int64) *ValidatingAdmissionPolicyStatusApplyConfiguration { + b.ObservedGeneration = &value + return b +} + +// WithTypeChecking sets the TypeChecking field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the TypeChecking field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyStatusApplyConfiguration) WithTypeChecking(value *TypeCheckingApplyConfiguration) *ValidatingAdmissionPolicyStatusApplyConfiguration { + b.TypeChecking = value + return b +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *ValidatingAdmissionPolicyStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *ValidatingAdmissionPolicyStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validation.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validation.go index 43916603b1..9a5fc8475a 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validation.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validation.go @@ -25,9 +25,10 @@ import ( // ValidationApplyConfiguration represents an declarative configuration of the Validation type for use // with apply. type ValidationApplyConfiguration struct { - Expression *string `json:"expression,omitempty"` - Message *string `json:"message,omitempty"` - Reason *v1.StatusReason `json:"reason,omitempty"` + Expression *string `json:"expression,omitempty"` + Message *string `json:"message,omitempty"` + Reason *v1.StatusReason `json:"reason,omitempty"` + MessageExpression *string `json:"messageExpression,omitempty"` } // ValidationApplyConfiguration constructs an declarative configuration of the Validation type for use with @@ -59,3 +60,11 @@ func (b *ValidationApplyConfiguration) WithReason(value v1.StatusReason) *Valida b.Reason = &value return b } + +// WithMessageExpression sets the MessageExpression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MessageExpression field is set to the value of the last call. +func (b *ValidationApplyConfiguration) WithMessageExpression(value string) *ValidationApplyConfiguration { + b.MessageExpression = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchcondition.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchcondition.go new file mode 100644 index 0000000000..d099b6b6ea --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchcondition.go @@ -0,0 +1,48 @@ +/* +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 applyconfiguration-gen. DO NOT EDIT. + +package v1beta1 + +// MatchConditionApplyConfiguration represents an declarative configuration of the MatchCondition type for use +// with apply. +type MatchConditionApplyConfiguration struct { + Name *string `json:"name,omitempty"` + Expression *string `json:"expression,omitempty"` +} + +// MatchConditionApplyConfiguration constructs an declarative configuration of the MatchCondition type for use with +// apply. +func MatchCondition() *MatchConditionApplyConfiguration { + return &MatchConditionApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithName(value string) *MatchConditionApplyConfiguration { + b.Name = &value + return b +} + +// WithExpression sets the Expression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Expression field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithExpression(value string) *MatchConditionApplyConfiguration { + b.Expression = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go index cc48d3b6f0..54845341f4 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go @@ -38,6 +38,7 @@ type MutatingWebhookApplyConfiguration struct { TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty"` ReinvocationPolicy *admissionregistrationv1beta1.ReinvocationPolicyType `json:"reinvocationPolicy,omitempty"` + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` } // MutatingWebhookApplyConfiguration constructs an declarative configuration of the MutatingWebhook type for use with @@ -140,3 +141,16 @@ func (b *MutatingWebhookApplyConfiguration) WithReinvocationPolicy(value admissi b.ReinvocationPolicy = &value return b } + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *MutatingWebhookApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *MutatingWebhookApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rule.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rule.go deleted file mode 100644 index 21151b9980..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rule.go +++ /dev/null @@ -1,76 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/admissionregistration/v1beta1" -) - -// RuleApplyConfiguration represents an declarative configuration of the Rule type for use -// with apply. -type RuleApplyConfiguration struct { - APIGroups []string `json:"apiGroups,omitempty"` - APIVersions []string `json:"apiVersions,omitempty"` - Resources []string `json:"resources,omitempty"` - Scope *v1beta1.ScopeType `json:"scope,omitempty"` -} - -// RuleApplyConfiguration constructs an declarative configuration of the Rule type for use with -// apply. -func Rule() *RuleApplyConfiguration { - return &RuleApplyConfiguration{} -} - -// WithAPIGroups adds the given value to the APIGroups field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIGroups field. -func (b *RuleApplyConfiguration) WithAPIGroups(values ...string) *RuleApplyConfiguration { - for i := range values { - b.APIGroups = append(b.APIGroups, values[i]) - } - return b -} - -// WithAPIVersions adds the given value to the APIVersions field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIVersions field. -func (b *RuleApplyConfiguration) WithAPIVersions(values ...string) *RuleApplyConfiguration { - for i := range values { - b.APIVersions = append(b.APIVersions, values[i]) - } - return b -} - -// WithResources adds the given value to the Resources field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Resources field. -func (b *RuleApplyConfiguration) WithResources(values ...string) *RuleApplyConfiguration { - for i := range values { - b.Resources = append(b.Resources, values[i]) - } - return b -} - -// WithScope sets the Scope field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Scope field is set to the value of the last call. -func (b *RuleApplyConfiguration) WithScope(value v1beta1.ScopeType) *RuleApplyConfiguration { - b.Scope = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rulewithoperations.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rulewithoperations.go deleted file mode 100644 index 0fd5dd34db..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rulewithoperations.go +++ /dev/null @@ -1,85 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1 "k8s.io/api/admissionregistration/v1" - admissionregistrationv1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1" -) - -// RuleWithOperationsApplyConfiguration represents an declarative configuration of the RuleWithOperations type for use -// with apply. -type RuleWithOperationsApplyConfiguration struct { - Operations []v1.OperationType `json:"operations,omitempty"` - admissionregistrationv1.RuleApplyConfiguration `json:",inline"` -} - -// RuleWithOperationsApplyConfiguration constructs an declarative configuration of the RuleWithOperations type for use with -// apply. -func RuleWithOperations() *RuleWithOperationsApplyConfiguration { - return &RuleWithOperationsApplyConfiguration{} -} - -// WithOperations adds the given value to the Operations field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Operations field. -func (b *RuleWithOperationsApplyConfiguration) WithOperations(values ...v1.OperationType) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.Operations = append(b.Operations, values[i]) - } - return b -} - -// WithAPIGroups adds the given value to the APIGroups field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIGroups field. -func (b *RuleWithOperationsApplyConfiguration) WithAPIGroups(values ...string) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.APIGroups = append(b.APIGroups, values[i]) - } - return b -} - -// WithAPIVersions adds the given value to the APIVersions field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIVersions field. -func (b *RuleWithOperationsApplyConfiguration) WithAPIVersions(values ...string) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.APIVersions = append(b.APIVersions, values[i]) - } - return b -} - -// WithResources adds the given value to the Resources field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Resources field. -func (b *RuleWithOperationsApplyConfiguration) WithResources(values ...string) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.Resources = append(b.Resources, values[i]) - } - return b -} - -// WithScope sets the Scope field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Scope field is set to the value of the last call. -func (b *RuleWithOperationsApplyConfiguration) WithScope(value v1.ScopeType) *RuleWithOperationsApplyConfiguration { - b.Scope = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go index 84479b5db3..8c5c341bad 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go @@ -37,6 +37,7 @@ type ValidatingWebhookApplyConfiguration struct { SideEffects *admissionregistrationv1beta1.SideEffectClass `json:"sideEffects,omitempty"` TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty"` + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` } // ValidatingWebhookApplyConfiguration constructs an declarative configuration of the ValidatingWebhook type for use with @@ -131,3 +132,16 @@ func (b *ValidatingWebhookApplyConfiguration) WithAdmissionReviewVersions(values } return b } + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *ValidatingWebhookApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *ValidatingWebhookApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2/podresourcemetricsource.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2/podresourcemetricsource.go deleted file mode 100644 index 86601cc48a..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2/podresourcemetricsource.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 applyconfiguration-gen. DO NOT EDIT. - -package v2 - -import ( - v1 "k8s.io/api/core/v1" -) - -// PodResourceMetricSourceApplyConfiguration represents an declarative configuration of the PodResourceMetricSource type for use -// with apply. -type PodResourceMetricSourceApplyConfiguration struct { - Name *v1.ResourceName `json:"name,omitempty"` - Target *MetricTargetApplyConfiguration `json:"target,omitempty"` -} - -// PodResourceMetricSourceApplyConfiguration constructs an declarative configuration of the PodResourceMetricSource type for use with -// apply. -func PodResourceMetricSource() *PodResourceMetricSourceApplyConfiguration { - return &PodResourceMetricSourceApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *PodResourceMetricSourceApplyConfiguration) WithName(value v1.ResourceName) *PodResourceMetricSourceApplyConfiguration { - b.Name = &value - return b -} - -// WithTarget sets the Target field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Target field is set to the value of the last call. -func (b *PodResourceMetricSourceApplyConfiguration) WithTarget(value *MetricTargetApplyConfiguration) *PodResourceMetricSourceApplyConfiguration { - b.Target = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podscheduling.go b/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundle.go similarity index 64% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podscheduling.go rename to vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundle.go index 44890c2d92..788d2a07dc 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podscheduling.go +++ b/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundle.go @@ -19,7 +19,7 @@ limitations under the License. package v1alpha1 import ( - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" managedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -27,66 +27,63 @@ import ( v1 "k8s.io/client-go/applyconfigurations/meta/v1" ) -// PodSchedulingApplyConfiguration represents an declarative configuration of the PodScheduling type for use +// ClusterTrustBundleApplyConfiguration represents an declarative configuration of the ClusterTrustBundle type for use // with apply. -type PodSchedulingApplyConfiguration struct { +type ClusterTrustBundleApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *PodSchedulingSpecApplyConfiguration `json:"spec,omitempty"` - Status *PodSchedulingStatusApplyConfiguration `json:"status,omitempty"` + Spec *ClusterTrustBundleSpecApplyConfiguration `json:"spec,omitempty"` } -// PodScheduling constructs an declarative configuration of the PodScheduling type for use with +// ClusterTrustBundle constructs an declarative configuration of the ClusterTrustBundle type for use with // apply. -func PodScheduling(name, namespace string) *PodSchedulingApplyConfiguration { - b := &PodSchedulingApplyConfiguration{} +func ClusterTrustBundle(name string) *ClusterTrustBundleApplyConfiguration { + b := &ClusterTrustBundleApplyConfiguration{} b.WithName(name) - b.WithNamespace(namespace) - b.WithKind("PodScheduling") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithKind("ClusterTrustBundle") + b.WithAPIVersion("certificates.k8s.io/v1alpha1") return b } -// ExtractPodScheduling extracts the applied configuration owned by fieldManager from -// podScheduling. If no managedFields are found in podScheduling for fieldManager, a -// PodSchedulingApplyConfiguration is returned with only the Name, Namespace (if applicable), +// ExtractClusterTrustBundle extracts the applied configuration owned by fieldManager from +// clusterTrustBundle. If no managedFields are found in clusterTrustBundle for fieldManager, a +// ClusterTrustBundleApplyConfiguration is returned with only the Name, Namespace (if applicable), // APIVersion and Kind populated. It is possible that no managed fields were found for because other // field managers have taken ownership of all the fields previously owned by fieldManager, or because // the fieldManager never owned fields any fields. -// podScheduling must be a unmodified PodScheduling API object that was retrieved from the Kubernetes API. -// ExtractPodScheduling provides a way to perform a extract/modify-in-place/apply workflow. +// clusterTrustBundle must be a unmodified ClusterTrustBundle API object that was retrieved from the Kubernetes API. +// ExtractClusterTrustBundle provides a way to perform a extract/modify-in-place/apply workflow. // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. // Experimental! -func ExtractPodScheduling(podScheduling *resourcev1alpha1.PodScheduling, fieldManager string) (*PodSchedulingApplyConfiguration, error) { - return extractPodScheduling(podScheduling, fieldManager, "") +func ExtractClusterTrustBundle(clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundle, fieldManager string) (*ClusterTrustBundleApplyConfiguration, error) { + return extractClusterTrustBundle(clusterTrustBundle, fieldManager, "") } -// ExtractPodSchedulingStatus is the same as ExtractPodScheduling except +// ExtractClusterTrustBundleStatus is the same as ExtractClusterTrustBundle except // that it extracts the status subresource applied configuration. // Experimental! -func ExtractPodSchedulingStatus(podScheduling *resourcev1alpha1.PodScheduling, fieldManager string) (*PodSchedulingApplyConfiguration, error) { - return extractPodScheduling(podScheduling, fieldManager, "status") +func ExtractClusterTrustBundleStatus(clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundle, fieldManager string) (*ClusterTrustBundleApplyConfiguration, error) { + return extractClusterTrustBundle(clusterTrustBundle, fieldManager, "status") } -func extractPodScheduling(podScheduling *resourcev1alpha1.PodScheduling, fieldManager string, subresource string) (*PodSchedulingApplyConfiguration, error) { - b := &PodSchedulingApplyConfiguration{} - err := managedfields.ExtractInto(podScheduling, internal.Parser().Type("io.k8s.api.resource.v1alpha1.PodScheduling"), fieldManager, b, subresource) +func extractClusterTrustBundle(clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundle, fieldManager string, subresource string) (*ClusterTrustBundleApplyConfiguration, error) { + b := &ClusterTrustBundleApplyConfiguration{} + err := managedfields.ExtractInto(clusterTrustBundle, internal.Parser().Type("io.k8s.api.certificates.v1alpha1.ClusterTrustBundle"), fieldManager, b, subresource) if err != nil { return nil, err } - b.WithName(podScheduling.Name) - b.WithNamespace(podScheduling.Namespace) + b.WithName(clusterTrustBundle.Name) - b.WithKind("PodScheduling") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithKind("ClusterTrustBundle") + b.WithAPIVersion("certificates.k8s.io/v1alpha1") return b, nil } // WithKind sets the Kind field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Kind field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithKind(value string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithKind(value string) *ClusterTrustBundleApplyConfiguration { b.Kind = &value return b } @@ -94,7 +91,7 @@ func (b *PodSchedulingApplyConfiguration) WithKind(value string) *PodSchedulingA // WithAPIVersion sets the APIVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the APIVersion field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithAPIVersion(value string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithAPIVersion(value string) *ClusterTrustBundleApplyConfiguration { b.APIVersion = &value return b } @@ -102,7 +99,7 @@ func (b *PodSchedulingApplyConfiguration) WithAPIVersion(value string) *PodSched // WithName sets the Name field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Name field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithName(value string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithName(value string) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.Name = &value return b @@ -111,7 +108,7 @@ func (b *PodSchedulingApplyConfiguration) WithName(value string) *PodSchedulingA // WithGenerateName sets the GenerateName field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the GenerateName field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithGenerateName(value string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithGenerateName(value string) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.GenerateName = &value return b @@ -120,7 +117,7 @@ func (b *PodSchedulingApplyConfiguration) WithGenerateName(value string) *PodSch // WithNamespace sets the Namespace field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Namespace field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithNamespace(value string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithNamespace(value string) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.Namespace = &value return b @@ -129,7 +126,7 @@ func (b *PodSchedulingApplyConfiguration) WithNamespace(value string) *PodSchedu // WithUID sets the UID field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the UID field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithUID(value types.UID) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithUID(value types.UID) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.UID = &value return b @@ -138,7 +135,7 @@ func (b *PodSchedulingApplyConfiguration) WithUID(value types.UID) *PodSchedulin // WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the ResourceVersion field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithResourceVersion(value string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithResourceVersion(value string) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ResourceVersion = &value return b @@ -147,7 +144,7 @@ func (b *PodSchedulingApplyConfiguration) WithResourceVersion(value string) *Pod // WithGeneration sets the Generation field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Generation field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithGeneration(value int64) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithGeneration(value int64) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.Generation = &value return b @@ -156,7 +153,7 @@ func (b *PodSchedulingApplyConfiguration) WithGeneration(value int64) *PodSchedu // WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the CreationTimestamp field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithCreationTimestamp(value metav1.Time) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.CreationTimestamp = &value return b @@ -165,7 +162,7 @@ func (b *PodSchedulingApplyConfiguration) WithCreationTimestamp(value metav1.Tim // WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionTimestamp field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.DeletionTimestamp = &value return b @@ -174,7 +171,7 @@ func (b *PodSchedulingApplyConfiguration) WithDeletionTimestamp(value metav1.Tim // WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.DeletionGracePeriodSeconds = &value return b @@ -184,7 +181,7 @@ func (b *PodSchedulingApplyConfiguration) WithDeletionGracePeriodSeconds(value i // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Labels field, // overwriting an existing map entries in Labels field with the same key. -func (b *PodSchedulingApplyConfiguration) WithLabels(entries map[string]string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithLabels(entries map[string]string) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.Labels == nil && len(entries) > 0 { b.Labels = make(map[string]string, len(entries)) @@ -199,7 +196,7 @@ func (b *PodSchedulingApplyConfiguration) WithLabels(entries map[string]string) // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Annotations field, // overwriting an existing map entries in Annotations field with the same key. -func (b *PodSchedulingApplyConfiguration) WithAnnotations(entries map[string]string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithAnnotations(entries map[string]string) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.Annotations == nil && len(entries) > 0 { b.Annotations = make(map[string]string, len(entries)) @@ -213,7 +210,7 @@ func (b *PodSchedulingApplyConfiguration) WithAnnotations(entries map[string]str // WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the OwnerReferences field. -func (b *PodSchedulingApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { if values[i] == nil { @@ -227,7 +224,7 @@ func (b *PodSchedulingApplyConfiguration) WithOwnerReferences(values ...*v1.Owne // WithFinalizers adds the given value to the Finalizers field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the Finalizers field. -func (b *PodSchedulingApplyConfiguration) WithFinalizers(values ...string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithFinalizers(values ...string) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { b.Finalizers = append(b.Finalizers, values[i]) @@ -235,7 +232,7 @@ func (b *PodSchedulingApplyConfiguration) WithFinalizers(values ...string) *PodS return b } -func (b *PodSchedulingApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { +func (b *ClusterTrustBundleApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { if b.ObjectMetaApplyConfiguration == nil { b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} } @@ -244,15 +241,7 @@ func (b *PodSchedulingApplyConfiguration) ensureObjectMetaApplyConfigurationExis // WithSpec sets the Spec field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Spec field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithSpec(value *PodSchedulingSpecApplyConfiguration) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithSpec(value *ClusterTrustBundleSpecApplyConfiguration) *ClusterTrustBundleApplyConfiguration { b.Spec = value return b } - -// WithStatus sets the Status field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Status field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithStatus(value *PodSchedulingStatusApplyConfiguration) *PodSchedulingApplyConfiguration { - b.Status = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundlespec.go b/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundlespec.go new file mode 100644 index 0000000000..d1aea1d6dc --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundlespec.go @@ -0,0 +1,48 @@ +/* +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 applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// ClusterTrustBundleSpecApplyConfiguration represents an declarative configuration of the ClusterTrustBundleSpec type for use +// with apply. +type ClusterTrustBundleSpecApplyConfiguration struct { + SignerName *string `json:"signerName,omitempty"` + TrustBundle *string `json:"trustBundle,omitempty"` +} + +// ClusterTrustBundleSpecApplyConfiguration constructs an declarative configuration of the ClusterTrustBundleSpec type for use with +// apply. +func ClusterTrustBundleSpec() *ClusterTrustBundleSpecApplyConfiguration { + return &ClusterTrustBundleSpecApplyConfiguration{} +} + +// WithSignerName sets the SignerName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the SignerName field is set to the value of the last call. +func (b *ClusterTrustBundleSpecApplyConfiguration) WithSignerName(value string) *ClusterTrustBundleSpecApplyConfiguration { + b.SignerName = &value + return b +} + +// WithTrustBundle sets the TrustBundle field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the TrustBundle field is set to the value of the last call. +func (b *ClusterTrustBundleSpecApplyConfiguration) WithTrustBundle(value string) *ClusterTrustBundleSpecApplyConfiguration { + b.TrustBundle = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/container.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/container.go index d3b066d9c4..9ada59ee20 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/container.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/container.go @@ -25,28 +25,29 @@ import ( // ContainerApplyConfiguration represents an declarative configuration of the Container type for use // with apply. type ContainerApplyConfiguration struct { - Name *string `json:"name,omitempty"` - Image *string `json:"image,omitempty"` - Command []string `json:"command,omitempty"` - Args []string `json:"args,omitempty"` - WorkingDir *string `json:"workingDir,omitempty"` - Ports []ContainerPortApplyConfiguration `json:"ports,omitempty"` - EnvFrom []EnvFromSourceApplyConfiguration `json:"envFrom,omitempty"` - Env []EnvVarApplyConfiguration `json:"env,omitempty"` - Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` - VolumeMounts []VolumeMountApplyConfiguration `json:"volumeMounts,omitempty"` - VolumeDevices []VolumeDeviceApplyConfiguration `json:"volumeDevices,omitempty"` - LivenessProbe *ProbeApplyConfiguration `json:"livenessProbe,omitempty"` - ReadinessProbe *ProbeApplyConfiguration `json:"readinessProbe,omitempty"` - StartupProbe *ProbeApplyConfiguration `json:"startupProbe,omitempty"` - Lifecycle *LifecycleApplyConfiguration `json:"lifecycle,omitempty"` - TerminationMessagePath *string `json:"terminationMessagePath,omitempty"` - TerminationMessagePolicy *corev1.TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty"` - ImagePullPolicy *corev1.PullPolicy `json:"imagePullPolicy,omitempty"` - SecurityContext *SecurityContextApplyConfiguration `json:"securityContext,omitempty"` - Stdin *bool `json:"stdin,omitempty"` - StdinOnce *bool `json:"stdinOnce,omitempty"` - TTY *bool `json:"tty,omitempty"` + Name *string `json:"name,omitempty"` + Image *string `json:"image,omitempty"` + Command []string `json:"command,omitempty"` + Args []string `json:"args,omitempty"` + WorkingDir *string `json:"workingDir,omitempty"` + Ports []ContainerPortApplyConfiguration `json:"ports,omitempty"` + EnvFrom []EnvFromSourceApplyConfiguration `json:"envFrom,omitempty"` + Env []EnvVarApplyConfiguration `json:"env,omitempty"` + Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` + ResizePolicy []ContainerResizePolicyApplyConfiguration `json:"resizePolicy,omitempty"` + VolumeMounts []VolumeMountApplyConfiguration `json:"volumeMounts,omitempty"` + VolumeDevices []VolumeDeviceApplyConfiguration `json:"volumeDevices,omitempty"` + LivenessProbe *ProbeApplyConfiguration `json:"livenessProbe,omitempty"` + ReadinessProbe *ProbeApplyConfiguration `json:"readinessProbe,omitempty"` + StartupProbe *ProbeApplyConfiguration `json:"startupProbe,omitempty"` + Lifecycle *LifecycleApplyConfiguration `json:"lifecycle,omitempty"` + TerminationMessagePath *string `json:"terminationMessagePath,omitempty"` + TerminationMessagePolicy *corev1.TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty"` + ImagePullPolicy *corev1.PullPolicy `json:"imagePullPolicy,omitempty"` + SecurityContext *SecurityContextApplyConfiguration `json:"securityContext,omitempty"` + Stdin *bool `json:"stdin,omitempty"` + StdinOnce *bool `json:"stdinOnce,omitempty"` + TTY *bool `json:"tty,omitempty"` } // ContainerApplyConfiguration constructs an declarative configuration of the Container type for use with @@ -146,6 +147,19 @@ func (b *ContainerApplyConfiguration) WithResources(value *ResourceRequirementsA return b } +// WithResizePolicy adds the given value to the ResizePolicy field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResizePolicy field. +func (b *ContainerApplyConfiguration) WithResizePolicy(values ...*ContainerResizePolicyApplyConfiguration) *ContainerApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResizePolicy") + } + b.ResizePolicy = append(b.ResizePolicy, *values[i]) + } + return b +} + // WithVolumeMounts adds the given value to the VolumeMounts field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the VolumeMounts field. diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerresizepolicy.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerresizepolicy.go new file mode 100644 index 0000000000..bbbcbc9f13 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerresizepolicy.go @@ -0,0 +1,52 @@ +/* +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 applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" +) + +// ContainerResizePolicyApplyConfiguration represents an declarative configuration of the ContainerResizePolicy type for use +// with apply. +type ContainerResizePolicyApplyConfiguration struct { + ResourceName *v1.ResourceName `json:"resourceName,omitempty"` + RestartPolicy *v1.ResourceResizeRestartPolicy `json:"restartPolicy,omitempty"` +} + +// ContainerResizePolicyApplyConfiguration constructs an declarative configuration of the ContainerResizePolicy type for use with +// apply. +func ContainerResizePolicy() *ContainerResizePolicyApplyConfiguration { + return &ContainerResizePolicyApplyConfiguration{} +} + +// WithResourceName sets the ResourceName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceName field is set to the value of the last call. +func (b *ContainerResizePolicyApplyConfiguration) WithResourceName(value v1.ResourceName) *ContainerResizePolicyApplyConfiguration { + b.ResourceName = &value + return b +} + +// WithRestartPolicy sets the RestartPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the RestartPolicy field is set to the value of the last call. +func (b *ContainerResizePolicyApplyConfiguration) WithRestartPolicy(value v1.ResourceResizeRestartPolicy) *ContainerResizePolicyApplyConfiguration { + b.RestartPolicy = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerstatus.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerstatus.go index 18d2925c17..2b98c4658f 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerstatus.go @@ -18,18 +18,24 @@ limitations under the License. package v1 +import ( + corev1 "k8s.io/api/core/v1" +) + // ContainerStatusApplyConfiguration represents an declarative configuration of the ContainerStatus type for use // with apply. type ContainerStatusApplyConfiguration struct { - Name *string `json:"name,omitempty"` - State *ContainerStateApplyConfiguration `json:"state,omitempty"` - LastTerminationState *ContainerStateApplyConfiguration `json:"lastState,omitempty"` - Ready *bool `json:"ready,omitempty"` - RestartCount *int32 `json:"restartCount,omitempty"` - Image *string `json:"image,omitempty"` - ImageID *string `json:"imageID,omitempty"` - ContainerID *string `json:"containerID,omitempty"` - Started *bool `json:"started,omitempty"` + Name *string `json:"name,omitempty"` + State *ContainerStateApplyConfiguration `json:"state,omitempty"` + LastTerminationState *ContainerStateApplyConfiguration `json:"lastState,omitempty"` + Ready *bool `json:"ready,omitempty"` + RestartCount *int32 `json:"restartCount,omitempty"` + Image *string `json:"image,omitempty"` + ImageID *string `json:"imageID,omitempty"` + ContainerID *string `json:"containerID,omitempty"` + Started *bool `json:"started,omitempty"` + AllocatedResources *corev1.ResourceList `json:"allocatedResources,omitempty"` + Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` } // ContainerStatusApplyConfiguration constructs an declarative configuration of the ContainerStatus type for use with @@ -109,3 +115,19 @@ func (b *ContainerStatusApplyConfiguration) WithStarted(value bool) *ContainerSt b.Started = &value return b } + +// WithAllocatedResources sets the AllocatedResources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the AllocatedResources field is set to the value of the last call. +func (b *ContainerStatusApplyConfiguration) WithAllocatedResources(value corev1.ResourceList) *ContainerStatusApplyConfiguration { + b.AllocatedResources = &value + return b +} + +// WithResources sets the Resources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Resources field is set to the value of the last call. +func (b *ContainerStatusApplyConfiguration) WithResources(value *ResourceRequirementsApplyConfiguration) *ContainerStatusApplyConfiguration { + b.Resources = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainer.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainer.go index 6c24cd419d..c51049ba1f 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainer.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainer.go @@ -126,6 +126,19 @@ func (b *EphemeralContainerApplyConfiguration) WithResources(value *ResourceRequ return b } +// WithResizePolicy adds the given value to the ResizePolicy field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResizePolicy field. +func (b *EphemeralContainerApplyConfiguration) WithResizePolicy(values ...*ContainerResizePolicyApplyConfiguration) *EphemeralContainerApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResizePolicy") + } + b.ResizePolicy = append(b.ResizePolicy, *values[i]) + } + return b +} + // WithVolumeMounts adds the given value to the VolumeMounts field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the VolumeMounts field. diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainercommon.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainercommon.go index 67e658cfab..764b830e04 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainercommon.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainercommon.go @@ -25,28 +25,29 @@ import ( // EphemeralContainerCommonApplyConfiguration represents an declarative configuration of the EphemeralContainerCommon type for use // with apply. type EphemeralContainerCommonApplyConfiguration struct { - Name *string `json:"name,omitempty"` - Image *string `json:"image,omitempty"` - Command []string `json:"command,omitempty"` - Args []string `json:"args,omitempty"` - WorkingDir *string `json:"workingDir,omitempty"` - Ports []ContainerPortApplyConfiguration `json:"ports,omitempty"` - EnvFrom []EnvFromSourceApplyConfiguration `json:"envFrom,omitempty"` - Env []EnvVarApplyConfiguration `json:"env,omitempty"` - Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` - VolumeMounts []VolumeMountApplyConfiguration `json:"volumeMounts,omitempty"` - VolumeDevices []VolumeDeviceApplyConfiguration `json:"volumeDevices,omitempty"` - LivenessProbe *ProbeApplyConfiguration `json:"livenessProbe,omitempty"` - ReadinessProbe *ProbeApplyConfiguration `json:"readinessProbe,omitempty"` - StartupProbe *ProbeApplyConfiguration `json:"startupProbe,omitempty"` - Lifecycle *LifecycleApplyConfiguration `json:"lifecycle,omitempty"` - TerminationMessagePath *string `json:"terminationMessagePath,omitempty"` - TerminationMessagePolicy *corev1.TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty"` - ImagePullPolicy *corev1.PullPolicy `json:"imagePullPolicy,omitempty"` - SecurityContext *SecurityContextApplyConfiguration `json:"securityContext,omitempty"` - Stdin *bool `json:"stdin,omitempty"` - StdinOnce *bool `json:"stdinOnce,omitempty"` - TTY *bool `json:"tty,omitempty"` + Name *string `json:"name,omitempty"` + Image *string `json:"image,omitempty"` + Command []string `json:"command,omitempty"` + Args []string `json:"args,omitempty"` + WorkingDir *string `json:"workingDir,omitempty"` + Ports []ContainerPortApplyConfiguration `json:"ports,omitempty"` + EnvFrom []EnvFromSourceApplyConfiguration `json:"envFrom,omitempty"` + Env []EnvVarApplyConfiguration `json:"env,omitempty"` + Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` + ResizePolicy []ContainerResizePolicyApplyConfiguration `json:"resizePolicy,omitempty"` + VolumeMounts []VolumeMountApplyConfiguration `json:"volumeMounts,omitempty"` + VolumeDevices []VolumeDeviceApplyConfiguration `json:"volumeDevices,omitempty"` + LivenessProbe *ProbeApplyConfiguration `json:"livenessProbe,omitempty"` + ReadinessProbe *ProbeApplyConfiguration `json:"readinessProbe,omitempty"` + StartupProbe *ProbeApplyConfiguration `json:"startupProbe,omitempty"` + Lifecycle *LifecycleApplyConfiguration `json:"lifecycle,omitempty"` + TerminationMessagePath *string `json:"terminationMessagePath,omitempty"` + TerminationMessagePolicy *corev1.TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty"` + ImagePullPolicy *corev1.PullPolicy `json:"imagePullPolicy,omitempty"` + SecurityContext *SecurityContextApplyConfiguration `json:"securityContext,omitempty"` + Stdin *bool `json:"stdin,omitempty"` + StdinOnce *bool `json:"stdinOnce,omitempty"` + TTY *bool `json:"tty,omitempty"` } // EphemeralContainerCommonApplyConfiguration constructs an declarative configuration of the EphemeralContainerCommon type for use with @@ -146,6 +147,19 @@ func (b *EphemeralContainerCommonApplyConfiguration) WithResources(value *Resour return b } +// WithResizePolicy adds the given value to the ResizePolicy field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResizePolicy field. +func (b *EphemeralContainerCommonApplyConfiguration) WithResizePolicy(values ...*ContainerResizePolicyApplyConfiguration) *EphemeralContainerCommonApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResizePolicy") + } + b.ResizePolicy = append(b.ResizePolicy, *values[i]) + } + return b +} + // WithVolumeMounts adds the given value to the VolumeMounts field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the VolumeMounts field. diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go index 7ee5b9955f..e9d8e5b28f 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go @@ -39,6 +39,7 @@ type PodStatusApplyConfiguration struct { ContainerStatuses []ContainerStatusApplyConfiguration `json:"containerStatuses,omitempty"` QOSClass *v1.PodQOSClass `json:"qosClass,omitempty"` EphemeralContainerStatuses []ContainerStatusApplyConfiguration `json:"ephemeralContainerStatuses,omitempty"` + Resize *v1.PodResizeStatus `json:"resize,omitempty"` } // PodStatusApplyConfiguration constructs an declarative configuration of the PodStatus type for use with @@ -175,3 +176,11 @@ func (b *PodStatusApplyConfiguration) WithEphemeralContainerStatuses(values ...* } return b } + +// WithResize sets the Resize field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Resize field is set to the value of the last call. +func (b *PodStatusApplyConfiguration) WithResize(value v1.PodResizeStatus) *PodStatusApplyConfiguration { + b.Resize = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/servicespec.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/servicespec.go index db376b941b..493af6fb3c 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/servicespec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/servicespec.go @@ -35,7 +35,7 @@ type ServiceSpecApplyConfiguration struct { LoadBalancerIP *string `json:"loadBalancerIP,omitempty"` LoadBalancerSourceRanges []string `json:"loadBalancerSourceRanges,omitempty"` ExternalName *string `json:"externalName,omitempty"` - ExternalTrafficPolicy *corev1.ServiceExternalTrafficPolicyType `json:"externalTrafficPolicy,omitempty"` + ExternalTrafficPolicy *corev1.ServiceExternalTrafficPolicy `json:"externalTrafficPolicy,omitempty"` HealthCheckNodePort *int32 `json:"healthCheckNodePort,omitempty"` PublishNotReadyAddresses *bool `json:"publishNotReadyAddresses,omitempty"` SessionAffinityConfig *SessionAffinityConfigApplyConfiguration `json:"sessionAffinityConfig,omitempty"` @@ -43,7 +43,7 @@ type ServiceSpecApplyConfiguration struct { IPFamilyPolicy *corev1.IPFamilyPolicy `json:"ipFamilyPolicy,omitempty"` AllocateLoadBalancerNodePorts *bool `json:"allocateLoadBalancerNodePorts,omitempty"` LoadBalancerClass *string `json:"loadBalancerClass,omitempty"` - InternalTrafficPolicy *corev1.ServiceInternalTrafficPolicyType `json:"internalTrafficPolicy,omitempty"` + InternalTrafficPolicy *corev1.ServiceInternalTrafficPolicy `json:"internalTrafficPolicy,omitempty"` } // ServiceSpecApplyConfiguration constructs an declarative configuration of the ServiceSpec type for use with @@ -152,7 +152,7 @@ func (b *ServiceSpecApplyConfiguration) WithExternalName(value string) *ServiceS // WithExternalTrafficPolicy sets the ExternalTrafficPolicy field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the ExternalTrafficPolicy field is set to the value of the last call. -func (b *ServiceSpecApplyConfiguration) WithExternalTrafficPolicy(value corev1.ServiceExternalTrafficPolicyType) *ServiceSpecApplyConfiguration { +func (b *ServiceSpecApplyConfiguration) WithExternalTrafficPolicy(value corev1.ServiceExternalTrafficPolicy) *ServiceSpecApplyConfiguration { b.ExternalTrafficPolicy = &value return b } @@ -218,7 +218,7 @@ func (b *ServiceSpecApplyConfiguration) WithLoadBalancerClass(value string) *Ser // WithInternalTrafficPolicy sets the InternalTrafficPolicy field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the InternalTrafficPolicy field is set to the value of the last call. -func (b *ServiceSpecApplyConfiguration) WithInternalTrafficPolicy(value corev1.ServiceInternalTrafficPolicyType) *ServiceSpecApplyConfiguration { +func (b *ServiceSpecApplyConfiguration) WithInternalTrafficPolicy(value corev1.ServiceInternalTrafficPolicy) *ServiceSpecApplyConfiguration { b.InternalTrafficPolicy = &value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedcsidriver.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedcsidriver.go deleted file mode 100644 index 27b49bf153..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedcsidriver.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 applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// AllowedCSIDriverApplyConfiguration represents an declarative configuration of the AllowedCSIDriver type for use -// with apply. -type AllowedCSIDriverApplyConfiguration struct { - Name *string `json:"name,omitempty"` -} - -// AllowedCSIDriverApplyConfiguration constructs an declarative configuration of the AllowedCSIDriver type for use with -// apply. -func AllowedCSIDriver() *AllowedCSIDriverApplyConfiguration { - return &AllowedCSIDriverApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *AllowedCSIDriverApplyConfiguration) WithName(value string) *AllowedCSIDriverApplyConfiguration { - b.Name = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedflexvolume.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedflexvolume.go deleted file mode 100644 index 30c3724cfe..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedflexvolume.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 applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// AllowedFlexVolumeApplyConfiguration represents an declarative configuration of the AllowedFlexVolume type for use -// with apply. -type AllowedFlexVolumeApplyConfiguration struct { - Driver *string `json:"driver,omitempty"` -} - -// AllowedFlexVolumeApplyConfiguration constructs an declarative configuration of the AllowedFlexVolume type for use with -// apply. -func AllowedFlexVolume() *AllowedFlexVolumeApplyConfiguration { - return &AllowedFlexVolumeApplyConfiguration{} -} - -// WithDriver sets the Driver field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Driver field is set to the value of the last call. -func (b *AllowedFlexVolumeApplyConfiguration) WithDriver(value string) *AllowedFlexVolumeApplyConfiguration { - b.Driver = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedhostpath.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedhostpath.go deleted file mode 100644 index 493815d8d4..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedhostpath.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 applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// AllowedHostPathApplyConfiguration represents an declarative configuration of the AllowedHostPath type for use -// with apply. -type AllowedHostPathApplyConfiguration struct { - PathPrefix *string `json:"pathPrefix,omitempty"` - ReadOnly *bool `json:"readOnly,omitempty"` -} - -// AllowedHostPathApplyConfiguration constructs an declarative configuration of the AllowedHostPath type for use with -// apply. -func AllowedHostPath() *AllowedHostPathApplyConfiguration { - return &AllowedHostPathApplyConfiguration{} -} - -// WithPathPrefix sets the PathPrefix field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the PathPrefix field is set to the value of the last call. -func (b *AllowedHostPathApplyConfiguration) WithPathPrefix(value string) *AllowedHostPathApplyConfiguration { - b.PathPrefix = &value - return b -} - -// WithReadOnly sets the ReadOnly field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ReadOnly field is set to the value of the last call. -func (b *AllowedHostPathApplyConfiguration) WithReadOnly(value bool) *AllowedHostPathApplyConfiguration { - b.ReadOnly = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/fsgroupstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/fsgroupstrategyoptions.go deleted file mode 100644 index c7434a6af0..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/fsgroupstrategyoptions.go +++ /dev/null @@ -1,57 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" -) - -// FSGroupStrategyOptionsApplyConfiguration represents an declarative configuration of the FSGroupStrategyOptions type for use -// with apply. -type FSGroupStrategyOptionsApplyConfiguration struct { - Rule *v1beta1.FSGroupStrategyType `json:"rule,omitempty"` - Ranges []IDRangeApplyConfiguration `json:"ranges,omitempty"` -} - -// FSGroupStrategyOptionsApplyConfiguration constructs an declarative configuration of the FSGroupStrategyOptions type for use with -// apply. -func FSGroupStrategyOptions() *FSGroupStrategyOptionsApplyConfiguration { - return &FSGroupStrategyOptionsApplyConfiguration{} -} - -// WithRule sets the Rule field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Rule field is set to the value of the last call. -func (b *FSGroupStrategyOptionsApplyConfiguration) WithRule(value v1beta1.FSGroupStrategyType) *FSGroupStrategyOptionsApplyConfiguration { - b.Rule = &value - return b -} - -// WithRanges adds the given value to the Ranges field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Ranges field. -func (b *FSGroupStrategyOptionsApplyConfiguration) WithRanges(values ...*IDRangeApplyConfiguration) *FSGroupStrategyOptionsApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithRanges") - } - b.Ranges = append(b.Ranges, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/hostportrange.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/hostportrange.go deleted file mode 100644 index 7c79688139..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/hostportrange.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 applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// HostPortRangeApplyConfiguration represents an declarative configuration of the HostPortRange type for use -// with apply. -type HostPortRangeApplyConfiguration struct { - Min *int32 `json:"min,omitempty"` - Max *int32 `json:"max,omitempty"` -} - -// HostPortRangeApplyConfiguration constructs an declarative configuration of the HostPortRange type for use with -// apply. -func HostPortRange() *HostPortRangeApplyConfiguration { - return &HostPortRangeApplyConfiguration{} -} - -// WithMin sets the Min field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Min field is set to the value of the last call. -func (b *HostPortRangeApplyConfiguration) WithMin(value int32) *HostPortRangeApplyConfiguration { - b.Min = &value - return b -} - -// WithMax sets the Max field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Max field is set to the value of the last call. -func (b *HostPortRangeApplyConfiguration) WithMax(value int32) *HostPortRangeApplyConfiguration { - b.Max = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/idrange.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/idrange.go deleted file mode 100644 index af46f76581..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/idrange.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 applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// IDRangeApplyConfiguration represents an declarative configuration of the IDRange type for use -// with apply. -type IDRangeApplyConfiguration struct { - Min *int64 `json:"min,omitempty"` - Max *int64 `json:"max,omitempty"` -} - -// IDRangeApplyConfiguration constructs an declarative configuration of the IDRange type for use with -// apply. -func IDRange() *IDRangeApplyConfiguration { - return &IDRangeApplyConfiguration{} -} - -// WithMin sets the Min field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Min field is set to the value of the last call. -func (b *IDRangeApplyConfiguration) WithMin(value int64) *IDRangeApplyConfiguration { - b.Min = &value - return b -} - -// WithMax sets the Max field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Max field is set to the value of the last call. -func (b *IDRangeApplyConfiguration) WithMax(value int64) *IDRangeApplyConfiguration { - b.Max = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicyspec.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicyspec.go deleted file mode 100644 index de3949dc92..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicyspec.go +++ /dev/null @@ -1,285 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1 "k8s.io/api/core/v1" - v1beta1 "k8s.io/api/extensions/v1beta1" -) - -// PodSecurityPolicySpecApplyConfiguration represents an declarative configuration of the PodSecurityPolicySpec type for use -// with apply. -type PodSecurityPolicySpecApplyConfiguration struct { - Privileged *bool `json:"privileged,omitempty"` - DefaultAddCapabilities []v1.Capability `json:"defaultAddCapabilities,omitempty"` - RequiredDropCapabilities []v1.Capability `json:"requiredDropCapabilities,omitempty"` - AllowedCapabilities []v1.Capability `json:"allowedCapabilities,omitempty"` - Volumes []v1beta1.FSType `json:"volumes,omitempty"` - HostNetwork *bool `json:"hostNetwork,omitempty"` - HostPorts []HostPortRangeApplyConfiguration `json:"hostPorts,omitempty"` - HostPID *bool `json:"hostPID,omitempty"` - HostIPC *bool `json:"hostIPC,omitempty"` - SELinux *SELinuxStrategyOptionsApplyConfiguration `json:"seLinux,omitempty"` - RunAsUser *RunAsUserStrategyOptionsApplyConfiguration `json:"runAsUser,omitempty"` - RunAsGroup *RunAsGroupStrategyOptionsApplyConfiguration `json:"runAsGroup,omitempty"` - SupplementalGroups *SupplementalGroupsStrategyOptionsApplyConfiguration `json:"supplementalGroups,omitempty"` - FSGroup *FSGroupStrategyOptionsApplyConfiguration `json:"fsGroup,omitempty"` - ReadOnlyRootFilesystem *bool `json:"readOnlyRootFilesystem,omitempty"` - DefaultAllowPrivilegeEscalation *bool `json:"defaultAllowPrivilegeEscalation,omitempty"` - AllowPrivilegeEscalation *bool `json:"allowPrivilegeEscalation,omitempty"` - AllowedHostPaths []AllowedHostPathApplyConfiguration `json:"allowedHostPaths,omitempty"` - AllowedFlexVolumes []AllowedFlexVolumeApplyConfiguration `json:"allowedFlexVolumes,omitempty"` - AllowedCSIDrivers []AllowedCSIDriverApplyConfiguration `json:"allowedCSIDrivers,omitempty"` - AllowedUnsafeSysctls []string `json:"allowedUnsafeSysctls,omitempty"` - ForbiddenSysctls []string `json:"forbiddenSysctls,omitempty"` - AllowedProcMountTypes []v1.ProcMountType `json:"allowedProcMountTypes,omitempty"` - RuntimeClass *RuntimeClassStrategyOptionsApplyConfiguration `json:"runtimeClass,omitempty"` -} - -// PodSecurityPolicySpecApplyConfiguration constructs an declarative configuration of the PodSecurityPolicySpec type for use with -// apply. -func PodSecurityPolicySpec() *PodSecurityPolicySpecApplyConfiguration { - return &PodSecurityPolicySpecApplyConfiguration{} -} - -// WithPrivileged sets the Privileged field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Privileged field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithPrivileged(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.Privileged = &value - return b -} - -// WithDefaultAddCapabilities adds the given value to the DefaultAddCapabilities field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the DefaultAddCapabilities field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithDefaultAddCapabilities(values ...v1.Capability) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.DefaultAddCapabilities = append(b.DefaultAddCapabilities, values[i]) - } - return b -} - -// WithRequiredDropCapabilities adds the given value to the RequiredDropCapabilities field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the RequiredDropCapabilities field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithRequiredDropCapabilities(values ...v1.Capability) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.RequiredDropCapabilities = append(b.RequiredDropCapabilities, values[i]) - } - return b -} - -// WithAllowedCapabilities adds the given value to the AllowedCapabilities field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedCapabilities field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedCapabilities(values ...v1.Capability) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.AllowedCapabilities = append(b.AllowedCapabilities, values[i]) - } - return b -} - -// WithVolumes adds the given value to the Volumes field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Volumes field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithVolumes(values ...v1beta1.FSType) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.Volumes = append(b.Volumes, values[i]) - } - return b -} - -// WithHostNetwork sets the HostNetwork field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the HostNetwork field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithHostNetwork(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.HostNetwork = &value - return b -} - -// WithHostPorts adds the given value to the HostPorts field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the HostPorts field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithHostPorts(values ...*HostPortRangeApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithHostPorts") - } - b.HostPorts = append(b.HostPorts, *values[i]) - } - return b -} - -// WithHostPID sets the HostPID field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the HostPID field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithHostPID(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.HostPID = &value - return b -} - -// WithHostIPC sets the HostIPC field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the HostIPC field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithHostIPC(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.HostIPC = &value - return b -} - -// WithSELinux sets the SELinux field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the SELinux field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithSELinux(value *SELinuxStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.SELinux = value - return b -} - -// WithRunAsUser sets the RunAsUser field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RunAsUser field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithRunAsUser(value *RunAsUserStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.RunAsUser = value - return b -} - -// WithRunAsGroup sets the RunAsGroup field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RunAsGroup field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithRunAsGroup(value *RunAsGroupStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.RunAsGroup = value - return b -} - -// WithSupplementalGroups sets the SupplementalGroups field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the SupplementalGroups field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithSupplementalGroups(value *SupplementalGroupsStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.SupplementalGroups = value - return b -} - -// WithFSGroup sets the FSGroup field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the FSGroup field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithFSGroup(value *FSGroupStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.FSGroup = value - return b -} - -// WithReadOnlyRootFilesystem sets the ReadOnlyRootFilesystem field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ReadOnlyRootFilesystem field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithReadOnlyRootFilesystem(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.ReadOnlyRootFilesystem = &value - return b -} - -// WithDefaultAllowPrivilegeEscalation sets the DefaultAllowPrivilegeEscalation field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the DefaultAllowPrivilegeEscalation field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithDefaultAllowPrivilegeEscalation(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.DefaultAllowPrivilegeEscalation = &value - return b -} - -// WithAllowPrivilegeEscalation sets the AllowPrivilegeEscalation field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the AllowPrivilegeEscalation field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowPrivilegeEscalation(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.AllowPrivilegeEscalation = &value - return b -} - -// WithAllowedHostPaths adds the given value to the AllowedHostPaths field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedHostPaths field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedHostPaths(values ...*AllowedHostPathApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithAllowedHostPaths") - } - b.AllowedHostPaths = append(b.AllowedHostPaths, *values[i]) - } - return b -} - -// WithAllowedFlexVolumes adds the given value to the AllowedFlexVolumes field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedFlexVolumes field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedFlexVolumes(values ...*AllowedFlexVolumeApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithAllowedFlexVolumes") - } - b.AllowedFlexVolumes = append(b.AllowedFlexVolumes, *values[i]) - } - return b -} - -// WithAllowedCSIDrivers adds the given value to the AllowedCSIDrivers field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedCSIDrivers field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedCSIDrivers(values ...*AllowedCSIDriverApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithAllowedCSIDrivers") - } - b.AllowedCSIDrivers = append(b.AllowedCSIDrivers, *values[i]) - } - return b -} - -// WithAllowedUnsafeSysctls adds the given value to the AllowedUnsafeSysctls field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedUnsafeSysctls field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedUnsafeSysctls(values ...string) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.AllowedUnsafeSysctls = append(b.AllowedUnsafeSysctls, values[i]) - } - return b -} - -// WithForbiddenSysctls adds the given value to the ForbiddenSysctls field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the ForbiddenSysctls field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithForbiddenSysctls(values ...string) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.ForbiddenSysctls = append(b.ForbiddenSysctls, values[i]) - } - return b -} - -// WithAllowedProcMountTypes adds the given value to the AllowedProcMountTypes field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedProcMountTypes field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedProcMountTypes(values ...v1.ProcMountType) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.AllowedProcMountTypes = append(b.AllowedProcMountTypes, values[i]) - } - return b -} - -// WithRuntimeClass sets the RuntimeClass field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RuntimeClass field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithRuntimeClass(value *RuntimeClassStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.RuntimeClass = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasgroupstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasgroupstrategyoptions.go deleted file mode 100644 index 75e76e85fd..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasgroupstrategyoptions.go +++ /dev/null @@ -1,57 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" -) - -// RunAsGroupStrategyOptionsApplyConfiguration represents an declarative configuration of the RunAsGroupStrategyOptions type for use -// with apply. -type RunAsGroupStrategyOptionsApplyConfiguration struct { - Rule *v1beta1.RunAsGroupStrategy `json:"rule,omitempty"` - Ranges []IDRangeApplyConfiguration `json:"ranges,omitempty"` -} - -// RunAsGroupStrategyOptionsApplyConfiguration constructs an declarative configuration of the RunAsGroupStrategyOptions type for use with -// apply. -func RunAsGroupStrategyOptions() *RunAsGroupStrategyOptionsApplyConfiguration { - return &RunAsGroupStrategyOptionsApplyConfiguration{} -} - -// WithRule sets the Rule field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Rule field is set to the value of the last call. -func (b *RunAsGroupStrategyOptionsApplyConfiguration) WithRule(value v1beta1.RunAsGroupStrategy) *RunAsGroupStrategyOptionsApplyConfiguration { - b.Rule = &value - return b -} - -// WithRanges adds the given value to the Ranges field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Ranges field. -func (b *RunAsGroupStrategyOptionsApplyConfiguration) WithRanges(values ...*IDRangeApplyConfiguration) *RunAsGroupStrategyOptionsApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithRanges") - } - b.Ranges = append(b.Ranges, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasuserstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasuserstrategyoptions.go deleted file mode 100644 index 712c1675ac..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasuserstrategyoptions.go +++ /dev/null @@ -1,57 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" -) - -// RunAsUserStrategyOptionsApplyConfiguration represents an declarative configuration of the RunAsUserStrategyOptions type for use -// with apply. -type RunAsUserStrategyOptionsApplyConfiguration struct { - Rule *v1beta1.RunAsUserStrategy `json:"rule,omitempty"` - Ranges []IDRangeApplyConfiguration `json:"ranges,omitempty"` -} - -// RunAsUserStrategyOptionsApplyConfiguration constructs an declarative configuration of the RunAsUserStrategyOptions type for use with -// apply. -func RunAsUserStrategyOptions() *RunAsUserStrategyOptionsApplyConfiguration { - return &RunAsUserStrategyOptionsApplyConfiguration{} -} - -// WithRule sets the Rule field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Rule field is set to the value of the last call. -func (b *RunAsUserStrategyOptionsApplyConfiguration) WithRule(value v1beta1.RunAsUserStrategy) *RunAsUserStrategyOptionsApplyConfiguration { - b.Rule = &value - return b -} - -// WithRanges adds the given value to the Ranges field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Ranges field. -func (b *RunAsUserStrategyOptionsApplyConfiguration) WithRanges(values ...*IDRangeApplyConfiguration) *RunAsUserStrategyOptionsApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithRanges") - } - b.Ranges = append(b.Ranges, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runtimeclassstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runtimeclassstrategyoptions.go deleted file mode 100644 index c19a7ce617..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runtimeclassstrategyoptions.go +++ /dev/null @@ -1,50 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// RuntimeClassStrategyOptionsApplyConfiguration represents an declarative configuration of the RuntimeClassStrategyOptions type for use -// with apply. -type RuntimeClassStrategyOptionsApplyConfiguration struct { - AllowedRuntimeClassNames []string `json:"allowedRuntimeClassNames,omitempty"` - DefaultRuntimeClassName *string `json:"defaultRuntimeClassName,omitempty"` -} - -// RuntimeClassStrategyOptionsApplyConfiguration constructs an declarative configuration of the RuntimeClassStrategyOptions type for use with -// apply. -func RuntimeClassStrategyOptions() *RuntimeClassStrategyOptionsApplyConfiguration { - return &RuntimeClassStrategyOptionsApplyConfiguration{} -} - -// WithAllowedRuntimeClassNames adds the given value to the AllowedRuntimeClassNames field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedRuntimeClassNames field. -func (b *RuntimeClassStrategyOptionsApplyConfiguration) WithAllowedRuntimeClassNames(values ...string) *RuntimeClassStrategyOptionsApplyConfiguration { - for i := range values { - b.AllowedRuntimeClassNames = append(b.AllowedRuntimeClassNames, values[i]) - } - return b -} - -// WithDefaultRuntimeClassName sets the DefaultRuntimeClassName field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the DefaultRuntimeClassName field is set to the value of the last call. -func (b *RuntimeClassStrategyOptionsApplyConfiguration) WithDefaultRuntimeClassName(value string) *RuntimeClassStrategyOptionsApplyConfiguration { - b.DefaultRuntimeClassName = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/selinuxstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/selinuxstrategyoptions.go deleted file mode 100644 index 265906a73a..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/selinuxstrategyoptions.go +++ /dev/null @@ -1,53 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" - v1 "k8s.io/client-go/applyconfigurations/core/v1" -) - -// SELinuxStrategyOptionsApplyConfiguration represents an declarative configuration of the SELinuxStrategyOptions type for use -// with apply. -type SELinuxStrategyOptionsApplyConfiguration struct { - Rule *v1beta1.SELinuxStrategy `json:"rule,omitempty"` - SELinuxOptions *v1.SELinuxOptionsApplyConfiguration `json:"seLinuxOptions,omitempty"` -} - -// SELinuxStrategyOptionsApplyConfiguration constructs an declarative configuration of the SELinuxStrategyOptions type for use with -// apply. -func SELinuxStrategyOptions() *SELinuxStrategyOptionsApplyConfiguration { - return &SELinuxStrategyOptionsApplyConfiguration{} -} - -// WithRule sets the Rule field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Rule field is set to the value of the last call. -func (b *SELinuxStrategyOptionsApplyConfiguration) WithRule(value v1beta1.SELinuxStrategy) *SELinuxStrategyOptionsApplyConfiguration { - b.Rule = &value - return b -} - -// WithSELinuxOptions sets the SELinuxOptions field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the SELinuxOptions field is set to the value of the last call. -func (b *SELinuxStrategyOptionsApplyConfiguration) WithSELinuxOptions(value *v1.SELinuxOptionsApplyConfiguration) *SELinuxStrategyOptionsApplyConfiguration { - b.SELinuxOptions = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/supplementalgroupsstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/supplementalgroupsstrategyoptions.go deleted file mode 100644 index ec43138124..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/supplementalgroupsstrategyoptions.go +++ /dev/null @@ -1,57 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" -) - -// SupplementalGroupsStrategyOptionsApplyConfiguration represents an declarative configuration of the SupplementalGroupsStrategyOptions type for use -// with apply. -type SupplementalGroupsStrategyOptionsApplyConfiguration struct { - Rule *v1beta1.SupplementalGroupsStrategyType `json:"rule,omitempty"` - Ranges []IDRangeApplyConfiguration `json:"ranges,omitempty"` -} - -// SupplementalGroupsStrategyOptionsApplyConfiguration constructs an declarative configuration of the SupplementalGroupsStrategyOptions type for use with -// apply. -func SupplementalGroupsStrategyOptions() *SupplementalGroupsStrategyOptionsApplyConfiguration { - return &SupplementalGroupsStrategyOptionsApplyConfiguration{} -} - -// WithRule sets the Rule field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Rule field is set to the value of the last call. -func (b *SupplementalGroupsStrategyOptionsApplyConfiguration) WithRule(value v1beta1.SupplementalGroupsStrategyType) *SupplementalGroupsStrategyOptionsApplyConfiguration { - b.Rule = &value - return b -} - -// WithRanges adds the given value to the Ranges field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Ranges field. -func (b *SupplementalGroupsStrategyOptionsApplyConfiguration) WithRanges(values ...*IDRangeApplyConfiguration) *SupplementalGroupsStrategyOptionsApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithRanges") - } - b.Ranges = append(b.Ranges, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go b/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go index afad3b12e1..361b2f4e85 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go +++ b/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go @@ -39,6 +39,17 @@ func Parser() *typed.Parser { var parserOnce sync.Once var parser *typed.Parser var schemaYAML = typed.YAMLObject(`types: +- name: io.k8s.api.admissionregistration.v1.MatchCondition + map: + fields: + - name: expression + type: + scalar: string + default: "" + - name: name + type: + scalar: string + default: "" - name: io.k8s.api.admissionregistration.v1.MutatingWebhook map: fields: @@ -55,6 +66,14 @@ var schemaYAML = typed.YAMLObject(`types: - name: failurePolicy type: scalar: string + - name: matchConditions + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1.MatchCondition + elementRelationship: associative + keys: + - name - name: matchPolicy type: scalar: string @@ -167,6 +186,14 @@ var schemaYAML = typed.YAMLObject(`types: - name: failurePolicy type: scalar: string + - name: matchConditions + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1.MatchCondition + elementRelationship: associative + keys: + - name - name: matchPolicy type: scalar: string @@ -225,6 +252,39 @@ var schemaYAML = typed.YAMLObject(`types: - name: url type: scalar: string +- name: io.k8s.api.admissionregistration.v1alpha1.AuditAnnotation + map: + fields: + - name: key + type: + scalar: string + default: "" + - name: valueExpression + type: + scalar: string + default: "" +- name: io.k8s.api.admissionregistration.v1alpha1.ExpressionWarning + map: + fields: + - name: fieldRef + type: + scalar: string + default: "" + - name: warning + type: + scalar: string + default: "" +- name: io.k8s.api.admissionregistration.v1alpha1.MatchCondition + map: + fields: + - name: expression + type: + scalar: string + default: "" + - name: name + type: + scalar: string + default: "" - name: io.k8s.api.admissionregistration.v1alpha1.MatchResources map: fields: @@ -307,6 +367,15 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string elementRelationship: atomic +- name: io.k8s.api.admissionregistration.v1alpha1.TypeChecking + map: + fields: + - name: expressionWarnings + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1alpha1.ExpressionWarning + elementRelationship: atomic - name: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicy map: fields: @@ -324,6 +393,10 @@ var schemaYAML = typed.YAMLObject(`types: type: namedType: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicySpec default: {} + - name: status + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyStatus + default: {} - name: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyBinding map: fields: @@ -353,12 +426,32 @@ var schemaYAML = typed.YAMLObject(`types: - name: policyName type: scalar: string + - name: validationActions + type: + list: + elementType: + scalar: string + elementRelationship: associative - name: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicySpec map: fields: + - name: auditAnnotations + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1alpha1.AuditAnnotation + elementRelationship: atomic - name: failurePolicy type: scalar: string + - name: matchConditions + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1alpha1.MatchCondition + elementRelationship: associative + keys: + - name - name: matchConstraints type: namedType: io.k8s.api.admissionregistration.v1alpha1.MatchResources @@ -371,6 +464,23 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: io.k8s.api.admissionregistration.v1alpha1.Validation elementRelationship: atomic +- name: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyStatus + map: + fields: + - name: conditions + type: + list: + elementType: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition + elementRelationship: associative + keys: + - type + - name: observedGeneration + type: + scalar: numeric + - name: typeChecking + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.TypeChecking - name: io.k8s.api.admissionregistration.v1alpha1.Validation map: fields: @@ -381,9 +491,23 @@ var schemaYAML = typed.YAMLObject(`types: - name: message type: scalar: string + - name: messageExpression + type: + scalar: string - name: reason type: scalar: string +- name: io.k8s.api.admissionregistration.v1beta1.MatchCondition + map: + fields: + - name: expression + type: + scalar: string + default: "" + - name: name + type: + scalar: string + default: "" - name: io.k8s.api.admissionregistration.v1beta1.MutatingWebhook map: fields: @@ -400,6 +524,14 @@ var schemaYAML = typed.YAMLObject(`types: - name: failurePolicy type: scalar: string + - name: matchConditions + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1beta1.MatchCondition + elementRelationship: associative + keys: + - name - name: matchPolicy type: scalar: string @@ -482,6 +614,14 @@ var schemaYAML = typed.YAMLObject(`types: - name: failurePolicy type: scalar: string + - name: matchConditions + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1beta1.MatchCondition + elementRelationship: associative + keys: + - name - name: matchPolicy type: scalar: string @@ -3502,6 +3642,33 @@ var schemaYAML = typed.YAMLObject(`types: elementRelationship: associative keys: - type +- name: io.k8s.api.certificates.v1alpha1.ClusterTrustBundle + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.certificates.v1alpha1.ClusterTrustBundleSpec + default: {} +- name: io.k8s.api.certificates.v1alpha1.ClusterTrustBundleSpec + map: + fields: + - name: signerName + type: + scalar: string + - name: trustBundle + type: + scalar: string + default: "" - name: io.k8s.api.certificates.v1beta1.CertificateSigningRequest map: fields: @@ -4129,6 +4296,12 @@ var schemaYAML = typed.YAMLObject(`types: - name: readinessProbe type: namedType: io.k8s.api.core.v1.Probe + - name: resizePolicy + type: + list: + elementType: + namedType: io.k8s.api.core.v1.ContainerResizePolicy + elementRelationship: atomic - name: resources type: namedType: io.k8s.api.core.v1.ResourceRequirements @@ -4205,6 +4378,17 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: TCP +- name: io.k8s.api.core.v1.ContainerResizePolicy + map: + fields: + - name: resourceName + type: + scalar: string + default: "" + - name: restartPolicy + type: + scalar: string + default: "" - name: io.k8s.api.core.v1.ContainerState map: fields: @@ -4263,6 +4447,11 @@ var schemaYAML = typed.YAMLObject(`types: - name: io.k8s.api.core.v1.ContainerStatus map: fields: + - name: allocatedResources + type: + map: + elementType: + namedType: io.k8s.apimachinery.pkg.api.resource.Quantity - name: containerID type: scalar: string @@ -4286,6 +4475,9 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: boolean default: false + - name: resources + type: + namedType: io.k8s.api.core.v1.ResourceRequirements - name: restartCount type: scalar: numeric @@ -4521,6 +4713,12 @@ var schemaYAML = typed.YAMLObject(`types: - name: readinessProbe type: namedType: io.k8s.api.core.v1.Probe + - name: resizePolicy + type: + list: + elementType: + namedType: io.k8s.api.core.v1.ContainerResizePolicy + elementRelationship: atomic - name: resources type: namedType: io.k8s.api.core.v1.ResourceRequirements @@ -6185,6 +6383,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: reason type: scalar: string + - name: resize + type: + scalar: string - name: startTime type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time @@ -6553,6 +6754,8 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: io.k8s.api.core.v1.ResourceClaim elementRelationship: associative + keys: + - name - name: limits type: map: @@ -7732,29 +7935,6 @@ var schemaYAML = typed.YAMLObject(`types: type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.MicroTime default: {} -- name: io.k8s.api.extensions.v1beta1.AllowedCSIDriver - map: - fields: - - name: name - type: - scalar: string - default: "" -- name: io.k8s.api.extensions.v1beta1.AllowedFlexVolume - map: - fields: - - name: driver - type: - scalar: string - default: "" -- name: io.k8s.api.extensions.v1beta1.AllowedHostPath - map: - fields: - - name: pathPrefix - type: - scalar: string - - name: readOnly - type: - scalar: boolean - name: io.k8s.api.extensions.v1beta1.DaemonSet map: fields: @@ -7990,18 +8170,6 @@ var schemaYAML = typed.YAMLObject(`types: - name: type type: scalar: string -- name: io.k8s.api.extensions.v1beta1.FSGroupStrategyOptions - map: - fields: - - name: ranges - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.IDRange - elementRelationship: atomic - - name: rule - type: - scalar: string - name: io.k8s.api.extensions.v1beta1.HTTPIngressPath map: fields: @@ -8024,28 +8192,6 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: io.k8s.api.extensions.v1beta1.HTTPIngressPath elementRelationship: atomic -- name: io.k8s.api.extensions.v1beta1.HostPortRange - map: - fields: - - name: max - type: - scalar: numeric - default: 0 - - name: min - type: - scalar: numeric - default: 0 -- name: io.k8s.api.extensions.v1beta1.IDRange - map: - fields: - - name: max - type: - scalar: numeric - default: 0 - - name: min - type: - scalar: numeric - default: 0 - name: io.k8s.api.extensions.v1beta1.IPBlock map: fields: @@ -8291,135 +8437,6 @@ var schemaYAML = typed.YAMLObject(`types: elementRelationship: associative keys: - type -- name: io.k8s.api.extensions.v1beta1.PodSecurityPolicy - map: - fields: - - name: apiVersion - type: - scalar: string - - name: kind - type: - scalar: string - - name: metadata - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta - default: {} - - name: spec - type: - namedType: io.k8s.api.extensions.v1beta1.PodSecurityPolicySpec - default: {} -- name: io.k8s.api.extensions.v1beta1.PodSecurityPolicySpec - map: - fields: - - name: allowPrivilegeEscalation - type: - scalar: boolean - - name: allowedCSIDrivers - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.AllowedCSIDriver - elementRelationship: atomic - - name: allowedCapabilities - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: allowedFlexVolumes - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.AllowedFlexVolume - elementRelationship: atomic - - name: allowedHostPaths - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.AllowedHostPath - elementRelationship: atomic - - name: allowedProcMountTypes - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: allowedUnsafeSysctls - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: defaultAddCapabilities - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: defaultAllowPrivilegeEscalation - type: - scalar: boolean - - name: forbiddenSysctls - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: fsGroup - type: - namedType: io.k8s.api.extensions.v1beta1.FSGroupStrategyOptions - default: {} - - name: hostIPC - type: - scalar: boolean - - name: hostNetwork - type: - scalar: boolean - - name: hostPID - type: - scalar: boolean - - name: hostPorts - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.HostPortRange - elementRelationship: atomic - - name: privileged - type: - scalar: boolean - - name: readOnlyRootFilesystem - type: - scalar: boolean - - name: requiredDropCapabilities - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: runAsGroup - type: - namedType: io.k8s.api.extensions.v1beta1.RunAsGroupStrategyOptions - - name: runAsUser - type: - namedType: io.k8s.api.extensions.v1beta1.RunAsUserStrategyOptions - default: {} - - name: runtimeClass - type: - namedType: io.k8s.api.extensions.v1beta1.RuntimeClassStrategyOptions - - name: seLinux - type: - namedType: io.k8s.api.extensions.v1beta1.SELinuxStrategyOptions - default: {} - - name: supplementalGroups - type: - namedType: io.k8s.api.extensions.v1beta1.SupplementalGroupsStrategyOptions - default: {} - - name: volumes - type: - list: - elementType: - scalar: string - elementRelationship: atomic - name: io.k8s.api.extensions.v1beta1.ReplicaSet map: fields: @@ -8529,66 +8546,6 @@ var schemaYAML = typed.YAMLObject(`types: - name: maxUnavailable type: namedType: io.k8s.apimachinery.pkg.util.intstr.IntOrString -- name: io.k8s.api.extensions.v1beta1.RunAsGroupStrategyOptions - map: - fields: - - name: ranges - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.IDRange - elementRelationship: atomic - - name: rule - type: - scalar: string - default: "" -- name: io.k8s.api.extensions.v1beta1.RunAsUserStrategyOptions - map: - fields: - - name: ranges - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.IDRange - elementRelationship: atomic - - name: rule - type: - scalar: string - default: "" -- name: io.k8s.api.extensions.v1beta1.RuntimeClassStrategyOptions - map: - fields: - - name: allowedRuntimeClassNames - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: defaultRuntimeClassName - type: - scalar: string -- name: io.k8s.api.extensions.v1beta1.SELinuxStrategyOptions - map: - fields: - - name: rule - type: - scalar: string - default: "" - - name: seLinuxOptions - type: - namedType: io.k8s.api.core.v1.SELinuxOptions -- name: io.k8s.api.extensions.v1beta1.SupplementalGroupsStrategyOptions - map: - fields: - - name: ranges - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.IDRange - elementRelationship: atomic - - name: rule - type: - scalar: string - name: io.k8s.api.flowcontrol.v1alpha1.FlowDistinguisherMethod map: fields: @@ -10268,6 +10225,47 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: numeric default: 0 +- name: io.k8s.api.networking.v1alpha1.IPAddress + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.networking.v1alpha1.IPAddressSpec + default: {} +- name: io.k8s.api.networking.v1alpha1.IPAddressSpec + map: + fields: + - name: parentRef + type: + namedType: io.k8s.api.networking.v1alpha1.ParentReference +- name: io.k8s.api.networking.v1alpha1.ParentReference + map: + fields: + - name: group + type: + scalar: string + - name: name + type: + scalar: string + - name: namespace + type: + scalar: string + - name: resource + type: + scalar: string + - name: uid + type: + scalar: string - name: io.k8s.api.networking.v1beta1.HTTPIngressPath map: fields: @@ -11507,19 +11505,22 @@ var schemaYAML = typed.YAMLObject(`types: - name: namespace type: scalar: string -- name: io.k8s.api.resource.v1alpha1.AllocationResult +- name: io.k8s.api.resource.v1alpha2.AllocationResult map: fields: - name: availableOnNodes type: namedType: io.k8s.api.core.v1.NodeSelector - - name: resourceHandle + - name: resourceHandles type: - scalar: string + list: + elementType: + namedType: io.k8s.api.resource.v1alpha2.ResourceHandle + elementRelationship: atomic - name: shareable type: scalar: boolean -- name: io.k8s.api.resource.v1alpha1.PodScheduling +- name: io.k8s.api.resource.v1alpha2.PodSchedulingContext map: fields: - name: apiVersion @@ -11534,13 +11535,13 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.resource.v1alpha1.PodSchedulingSpec + namedType: io.k8s.api.resource.v1alpha2.PodSchedulingContextSpec default: {} - name: status type: - namedType: io.k8s.api.resource.v1alpha1.PodSchedulingStatus + namedType: io.k8s.api.resource.v1alpha2.PodSchedulingContextStatus default: {} -- name: io.k8s.api.resource.v1alpha1.PodSchedulingSpec +- name: io.k8s.api.resource.v1alpha2.PodSchedulingContextSpec map: fields: - name: potentialNodes @@ -11552,18 +11553,18 @@ var schemaYAML = typed.YAMLObject(`types: - name: selectedNode type: scalar: string -- name: io.k8s.api.resource.v1alpha1.PodSchedulingStatus +- name: io.k8s.api.resource.v1alpha2.PodSchedulingContextStatus map: fields: - name: resourceClaims type: list: elementType: - namedType: io.k8s.api.resource.v1alpha1.ResourceClaimSchedulingStatus + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimSchedulingStatus elementRelationship: associative keys: - name -- name: io.k8s.api.resource.v1alpha1.ResourceClaim +- name: io.k8s.api.resource.v1alpha2.ResourceClaim map: fields: - name: apiVersion @@ -11578,13 +11579,13 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.resource.v1alpha1.ResourceClaimSpec + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimSpec default: {} - name: status type: - namedType: io.k8s.api.resource.v1alpha1.ResourceClaimStatus + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimStatus default: {} -- name: io.k8s.api.resource.v1alpha1.ResourceClaimConsumerReference +- name: io.k8s.api.resource.v1alpha2.ResourceClaimConsumerReference map: fields: - name: apiGroup @@ -11602,7 +11603,7 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" -- name: io.k8s.api.resource.v1alpha1.ResourceClaimParametersReference +- name: io.k8s.api.resource.v1alpha2.ResourceClaimParametersReference map: fields: - name: apiGroup @@ -11616,7 +11617,7 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" -- name: io.k8s.api.resource.v1alpha1.ResourceClaimSchedulingStatus +- name: io.k8s.api.resource.v1alpha2.ResourceClaimSchedulingStatus map: fields: - name: name @@ -11628,7 +11629,7 @@ var schemaYAML = typed.YAMLObject(`types: elementType: scalar: string elementRelationship: associative -- name: io.k8s.api.resource.v1alpha1.ResourceClaimSpec +- name: io.k8s.api.resource.v1alpha2.ResourceClaimSpec map: fields: - name: allocationMode @@ -11636,17 +11637,17 @@ var schemaYAML = typed.YAMLObject(`types: scalar: string - name: parametersRef type: - namedType: io.k8s.api.resource.v1alpha1.ResourceClaimParametersReference + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimParametersReference - name: resourceClassName type: scalar: string default: "" -- name: io.k8s.api.resource.v1alpha1.ResourceClaimStatus +- name: io.k8s.api.resource.v1alpha2.ResourceClaimStatus map: fields: - name: allocation type: - namedType: io.k8s.api.resource.v1alpha1.AllocationResult + namedType: io.k8s.api.resource.v1alpha2.AllocationResult - name: deallocationRequested type: scalar: boolean @@ -11657,9 +11658,11 @@ var schemaYAML = typed.YAMLObject(`types: type: list: elementType: - namedType: io.k8s.api.resource.v1alpha1.ResourceClaimConsumerReference + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimConsumerReference elementRelationship: associative -- name: io.k8s.api.resource.v1alpha1.ResourceClaimTemplate + keys: + - uid +- name: io.k8s.api.resource.v1alpha2.ResourceClaimTemplate map: fields: - name: apiVersion @@ -11674,9 +11677,9 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.resource.v1alpha1.ResourceClaimTemplateSpec + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimTemplateSpec default: {} -- name: io.k8s.api.resource.v1alpha1.ResourceClaimTemplateSpec +- name: io.k8s.api.resource.v1alpha2.ResourceClaimTemplateSpec map: fields: - name: metadata @@ -11685,9 +11688,9 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.resource.v1alpha1.ResourceClaimSpec + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimSpec default: {} -- name: io.k8s.api.resource.v1alpha1.ResourceClass +- name: io.k8s.api.resource.v1alpha2.ResourceClass map: fields: - name: apiVersion @@ -11706,11 +11709,11 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: parametersRef type: - namedType: io.k8s.api.resource.v1alpha1.ResourceClassParametersReference + namedType: io.k8s.api.resource.v1alpha2.ResourceClassParametersReference - name: suitableNodes type: namedType: io.k8s.api.core.v1.NodeSelector -- name: io.k8s.api.resource.v1alpha1.ResourceClassParametersReference +- name: io.k8s.api.resource.v1alpha2.ResourceClassParametersReference map: fields: - name: apiGroup @@ -11727,6 +11730,15 @@ var schemaYAML = typed.YAMLObject(`types: - name: namespace type: scalar: string +- name: io.k8s.api.resource.v1alpha2.ResourceHandle + map: + fields: + - name: data + type: + scalar: string + - name: driverName + type: + scalar: string - name: io.k8s.api.scheduling.v1.PriorityClass map: fields: diff --git a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/groupversionkind.go b/vendor/k8s.io/client-go/applyconfigurations/meta/v1/groupversionkind.go deleted file mode 100644 index f400e51649..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/groupversionkind.go +++ /dev/null @@ -1,57 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1 - -// GroupVersionKindApplyConfiguration represents an declarative configuration of the GroupVersionKind type for use -// with apply. -type GroupVersionKindApplyConfiguration struct { - Group *string `json:"group,omitempty"` - Version *string `json:"version,omitempty"` - Kind *string `json:"kind,omitempty"` -} - -// GroupVersionKindApplyConfiguration constructs an declarative configuration of the GroupVersionKind type for use with -// apply. -func GroupVersionKind() *GroupVersionKindApplyConfiguration { - return &GroupVersionKindApplyConfiguration{} -} - -// WithGroup sets the Group field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Group field is set to the value of the last call. -func (b *GroupVersionKindApplyConfiguration) WithGroup(value string) *GroupVersionKindApplyConfiguration { - b.Group = &value - return b -} - -// WithVersion sets the Version field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Version field is set to the value of the last call. -func (b *GroupVersionKindApplyConfiguration) WithVersion(value string) *GroupVersionKindApplyConfiguration { - b.Version = &value - return b -} - -// WithKind sets the Kind field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Kind field is set to the value of the last call. -func (b *GroupVersionKindApplyConfiguration) WithKind(value string) *GroupVersionKindApplyConfiguration { - b.Kind = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/listmeta.go b/vendor/k8s.io/client-go/applyconfigurations/meta/v1/listmeta.go deleted file mode 100644 index 5cadee3353..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/listmeta.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 applyconfiguration-gen. DO NOT EDIT. - -package v1 - -// ListMetaApplyConfiguration represents an declarative configuration of the ListMeta type for use -// with apply. -type ListMetaApplyConfiguration struct { - SelfLink *string `json:"selfLink,omitempty"` - ResourceVersion *string `json:"resourceVersion,omitempty"` - Continue *string `json:"continue,omitempty"` - RemainingItemCount *int64 `json:"remainingItemCount,omitempty"` -} - -// ListMetaApplyConfiguration constructs an declarative configuration of the ListMeta type for use with -// apply. -func ListMeta() *ListMetaApplyConfiguration { - return &ListMetaApplyConfiguration{} -} - -// WithSelfLink sets the SelfLink field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the SelfLink field is set to the value of the last call. -func (b *ListMetaApplyConfiguration) WithSelfLink(value string) *ListMetaApplyConfiguration { - b.SelfLink = &value - return b -} - -// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ResourceVersion field is set to the value of the last call. -func (b *ListMetaApplyConfiguration) WithResourceVersion(value string) *ListMetaApplyConfiguration { - b.ResourceVersion = &value - return b -} - -// WithContinue sets the Continue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Continue field is set to the value of the last call. -func (b *ListMetaApplyConfiguration) WithContinue(value string) *ListMetaApplyConfiguration { - b.Continue = &value - return b -} - -// WithRemainingItemCount sets the RemainingItemCount field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RemainingItemCount field is set to the value of the last call. -func (b *ListMetaApplyConfiguration) WithRemainingItemCount(value int64) *ListMetaApplyConfiguration { - b.RemainingItemCount = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/status.go b/vendor/k8s.io/client-go/applyconfigurations/meta/v1/status.go deleted file mode 100644 index 7db432089e..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/status.go +++ /dev/null @@ -1,142 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// StatusApplyConfiguration represents an declarative configuration of the Status type for use -// with apply. -type StatusApplyConfiguration struct { - TypeMetaApplyConfiguration `json:",inline"` - *ListMetaApplyConfiguration `json:"metadata,omitempty"` - Status *string `json:"status,omitempty"` - Message *string `json:"message,omitempty"` - Reason *metav1.StatusReason `json:"reason,omitempty"` - Details *StatusDetailsApplyConfiguration `json:"details,omitempty"` - Code *int32 `json:"code,omitempty"` -} - -// StatusApplyConfiguration constructs an declarative configuration of the Status type for use with -// apply. -func Status() *StatusApplyConfiguration { - b := &StatusApplyConfiguration{} - b.WithKind("Status") - b.WithAPIVersion("meta.k8s.io/v1") - return b -} - -// WithKind sets the Kind field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Kind field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithKind(value string) *StatusApplyConfiguration { - b.Kind = &value - return b -} - -// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the APIVersion field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithAPIVersion(value string) *StatusApplyConfiguration { - b.APIVersion = &value - return b -} - -// WithSelfLink sets the SelfLink field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the SelfLink field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithSelfLink(value string) *StatusApplyConfiguration { - b.ensureListMetaApplyConfigurationExists() - b.SelfLink = &value - return b -} - -// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ResourceVersion field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithResourceVersion(value string) *StatusApplyConfiguration { - b.ensureListMetaApplyConfigurationExists() - b.ResourceVersion = &value - return b -} - -// WithContinue sets the Continue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Continue field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithContinue(value string) *StatusApplyConfiguration { - b.ensureListMetaApplyConfigurationExists() - b.Continue = &value - return b -} - -// WithRemainingItemCount sets the RemainingItemCount field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RemainingItemCount field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithRemainingItemCount(value int64) *StatusApplyConfiguration { - b.ensureListMetaApplyConfigurationExists() - b.RemainingItemCount = &value - return b -} - -func (b *StatusApplyConfiguration) ensureListMetaApplyConfigurationExists() { - if b.ListMetaApplyConfiguration == nil { - b.ListMetaApplyConfiguration = &ListMetaApplyConfiguration{} - } -} - -// WithStatus sets the Status field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Status field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithStatus(value string) *StatusApplyConfiguration { - b.Status = &value - return b -} - -// WithMessage sets the Message field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Message field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithMessage(value string) *StatusApplyConfiguration { - b.Message = &value - return b -} - -// WithReason sets the Reason field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Reason field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithReason(value metav1.StatusReason) *StatusApplyConfiguration { - b.Reason = &value - return b -} - -// WithDetails sets the Details field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Details field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithDetails(value *StatusDetailsApplyConfiguration) *StatusApplyConfiguration { - b.Details = value - return b -} - -// WithCode sets the Code field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Code field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithCode(value int32) *StatusApplyConfiguration { - b.Code = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/statuscause.go b/vendor/k8s.io/client-go/applyconfigurations/meta/v1/statuscause.go deleted file mode 100644 index 7f05bca498..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/statuscause.go +++ /dev/null @@ -1,61 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1 - -import ( - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// StatusCauseApplyConfiguration represents an declarative configuration of the StatusCause type for use -// with apply. -type StatusCauseApplyConfiguration struct { - Type *v1.CauseType `json:"reason,omitempty"` - Message *string `json:"message,omitempty"` - Field *string `json:"field,omitempty"` -} - -// StatusCauseApplyConfiguration constructs an declarative configuration of the StatusCause type for use with -// apply. -func StatusCause() *StatusCauseApplyConfiguration { - return &StatusCauseApplyConfiguration{} -} - -// WithType sets the Type field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Type field is set to the value of the last call. -func (b *StatusCauseApplyConfiguration) WithType(value v1.CauseType) *StatusCauseApplyConfiguration { - b.Type = &value - return b -} - -// WithMessage sets the Message field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Message field is set to the value of the last call. -func (b *StatusCauseApplyConfiguration) WithMessage(value string) *StatusCauseApplyConfiguration { - b.Message = &value - return b -} - -// WithField sets the Field field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Field field is set to the value of the last call. -func (b *StatusCauseApplyConfiguration) WithField(value string) *StatusCauseApplyConfiguration { - b.Field = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/statusdetails.go b/vendor/k8s.io/client-go/applyconfigurations/meta/v1/statusdetails.go deleted file mode 100644 index a7dbaa1b26..0000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/statusdetails.go +++ /dev/null @@ -1,93 +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 applyconfiguration-gen. DO NOT EDIT. - -package v1 - -import ( - types "k8s.io/apimachinery/pkg/types" -) - -// StatusDetailsApplyConfiguration represents an declarative configuration of the StatusDetails type for use -// with apply. -type StatusDetailsApplyConfiguration struct { - Name *string `json:"name,omitempty"` - Group *string `json:"group,omitempty"` - Kind *string `json:"kind,omitempty"` - UID *types.UID `json:"uid,omitempty"` - Causes []StatusCauseApplyConfiguration `json:"causes,omitempty"` - RetryAfterSeconds *int32 `json:"retryAfterSeconds,omitempty"` -} - -// StatusDetailsApplyConfiguration constructs an declarative configuration of the StatusDetails type for use with -// apply. -func StatusDetails() *StatusDetailsApplyConfiguration { - return &StatusDetailsApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *StatusDetailsApplyConfiguration) WithName(value string) *StatusDetailsApplyConfiguration { - b.Name = &value - return b -} - -// WithGroup sets the Group field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Group field is set to the value of the last call. -func (b *StatusDetailsApplyConfiguration) WithGroup(value string) *StatusDetailsApplyConfiguration { - b.Group = &value - return b -} - -// WithKind sets the Kind field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Kind field is set to the value of the last call. -func (b *StatusDetailsApplyConfiguration) WithKind(value string) *StatusDetailsApplyConfiguration { - b.Kind = &value - return b -} - -// WithUID sets the UID field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the UID field is set to the value of the last call. -func (b *StatusDetailsApplyConfiguration) WithUID(value types.UID) *StatusDetailsApplyConfiguration { - b.UID = &value - return b -} - -// WithCauses adds the given value to the Causes field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Causes field. -func (b *StatusDetailsApplyConfiguration) WithCauses(values ...*StatusCauseApplyConfiguration) *StatusDetailsApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithCauses") - } - b.Causes = append(b.Causes, *values[i]) - } - return b -} - -// WithRetryAfterSeconds sets the RetryAfterSeconds field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RetryAfterSeconds field is set to the value of the last call. -func (b *StatusDetailsApplyConfiguration) WithRetryAfterSeconds(value int32) *StatusDetailsApplyConfiguration { - b.RetryAfterSeconds = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicy.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddress.go similarity index 66% rename from vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicy.go rename to vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddress.go index c70906cfaf..da6822111d 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicy.go +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddress.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1beta1 +package v1alpha1 import ( - extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + networkingv1alpha1 "k8s.io/api/networking/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" managedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -27,63 +27,63 @@ import ( v1 "k8s.io/client-go/applyconfigurations/meta/v1" ) -// PodSecurityPolicyApplyConfiguration represents an declarative configuration of the PodSecurityPolicy type for use +// IPAddressApplyConfiguration represents an declarative configuration of the IPAddress type for use // with apply. -type PodSecurityPolicyApplyConfiguration struct { +type IPAddressApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *PodSecurityPolicySpecApplyConfiguration `json:"spec,omitempty"` + Spec *IPAddressSpecApplyConfiguration `json:"spec,omitempty"` } -// PodSecurityPolicy constructs an declarative configuration of the PodSecurityPolicy type for use with +// IPAddress constructs an declarative configuration of the IPAddress type for use with // apply. -func PodSecurityPolicy(name string) *PodSecurityPolicyApplyConfiguration { - b := &PodSecurityPolicyApplyConfiguration{} +func IPAddress(name string) *IPAddressApplyConfiguration { + b := &IPAddressApplyConfiguration{} b.WithName(name) - b.WithKind("PodSecurityPolicy") - b.WithAPIVersion("extensions/v1beta1") + b.WithKind("IPAddress") + b.WithAPIVersion("networking.k8s.io/v1alpha1") return b } -// ExtractPodSecurityPolicy extracts the applied configuration owned by fieldManager from -// podSecurityPolicy. If no managedFields are found in podSecurityPolicy for fieldManager, a -// PodSecurityPolicyApplyConfiguration is returned with only the Name, Namespace (if applicable), +// ExtractIPAddress extracts the applied configuration owned by fieldManager from +// iPAddress. If no managedFields are found in iPAddress for fieldManager, a +// IPAddressApplyConfiguration is returned with only the Name, Namespace (if applicable), // APIVersion and Kind populated. It is possible that no managed fields were found for because other // field managers have taken ownership of all the fields previously owned by fieldManager, or because // the fieldManager never owned fields any fields. -// podSecurityPolicy must be a unmodified PodSecurityPolicy API object that was retrieved from the Kubernetes API. -// ExtractPodSecurityPolicy provides a way to perform a extract/modify-in-place/apply workflow. +// iPAddress must be a unmodified IPAddress API object that was retrieved from the Kubernetes API. +// ExtractIPAddress provides a way to perform a extract/modify-in-place/apply workflow. // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. // Experimental! -func ExtractPodSecurityPolicy(podSecurityPolicy *extensionsv1beta1.PodSecurityPolicy, fieldManager string) (*PodSecurityPolicyApplyConfiguration, error) { - return extractPodSecurityPolicy(podSecurityPolicy, fieldManager, "") +func ExtractIPAddress(iPAddress *networkingv1alpha1.IPAddress, fieldManager string) (*IPAddressApplyConfiguration, error) { + return extractIPAddress(iPAddress, fieldManager, "") } -// ExtractPodSecurityPolicyStatus is the same as ExtractPodSecurityPolicy except +// ExtractIPAddressStatus is the same as ExtractIPAddress except // that it extracts the status subresource applied configuration. // Experimental! -func ExtractPodSecurityPolicyStatus(podSecurityPolicy *extensionsv1beta1.PodSecurityPolicy, fieldManager string) (*PodSecurityPolicyApplyConfiguration, error) { - return extractPodSecurityPolicy(podSecurityPolicy, fieldManager, "status") +func ExtractIPAddressStatus(iPAddress *networkingv1alpha1.IPAddress, fieldManager string) (*IPAddressApplyConfiguration, error) { + return extractIPAddress(iPAddress, fieldManager, "status") } -func extractPodSecurityPolicy(podSecurityPolicy *extensionsv1beta1.PodSecurityPolicy, fieldManager string, subresource string) (*PodSecurityPolicyApplyConfiguration, error) { - b := &PodSecurityPolicyApplyConfiguration{} - err := managedfields.ExtractInto(podSecurityPolicy, internal.Parser().Type("io.k8s.api.extensions.v1beta1.PodSecurityPolicy"), fieldManager, b, subresource) +func extractIPAddress(iPAddress *networkingv1alpha1.IPAddress, fieldManager string, subresource string) (*IPAddressApplyConfiguration, error) { + b := &IPAddressApplyConfiguration{} + err := managedfields.ExtractInto(iPAddress, internal.Parser().Type("io.k8s.api.networking.v1alpha1.IPAddress"), fieldManager, b, subresource) if err != nil { return nil, err } - b.WithName(podSecurityPolicy.Name) + b.WithName(iPAddress.Name) - b.WithKind("PodSecurityPolicy") - b.WithAPIVersion("extensions/v1beta1") + b.WithKind("IPAddress") + b.WithAPIVersion("networking.k8s.io/v1alpha1") return b, nil } // WithKind sets the Kind field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Kind field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithKind(value string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithKind(value string) *IPAddressApplyConfiguration { b.Kind = &value return b } @@ -91,7 +91,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithKind(value string) *PodSecurit // WithAPIVersion sets the APIVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the APIVersion field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithAPIVersion(value string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithAPIVersion(value string) *IPAddressApplyConfiguration { b.APIVersion = &value return b } @@ -99,7 +99,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithAPIVersion(value string) *PodS // WithName sets the Name field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Name field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithName(value string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithName(value string) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.Name = &value return b @@ -108,7 +108,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithName(value string) *PodSecurit // WithGenerateName sets the GenerateName field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the GenerateName field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithGenerateName(value string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithGenerateName(value string) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.GenerateName = &value return b @@ -117,7 +117,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithGenerateName(value string) *Po // WithNamespace sets the Namespace field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Namespace field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithNamespace(value string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithNamespace(value string) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.Namespace = &value return b @@ -126,7 +126,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithNamespace(value string) *PodSe // WithUID sets the UID field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the UID field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithUID(value types.UID) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithUID(value types.UID) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.UID = &value return b @@ -135,7 +135,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithUID(value types.UID) *PodSecur // WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the ResourceVersion field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithResourceVersion(value string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithResourceVersion(value string) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ResourceVersion = &value return b @@ -144,7 +144,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithResourceVersion(value string) // WithGeneration sets the Generation field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Generation field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithGeneration(value int64) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithGeneration(value int64) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.Generation = &value return b @@ -153,7 +153,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithGeneration(value int64) *PodSe // WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the CreationTimestamp field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithCreationTimestamp(value metav1.Time) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithCreationTimestamp(value metav1.Time) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.CreationTimestamp = &value return b @@ -162,7 +162,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithCreationTimestamp(value metav1 // WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionTimestamp field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.DeletionTimestamp = &value return b @@ -171,7 +171,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithDeletionTimestamp(value metav1 // WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.DeletionGracePeriodSeconds = &value return b @@ -181,7 +181,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithDeletionGracePeriodSeconds(val // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Labels field, // overwriting an existing map entries in Labels field with the same key. -func (b *PodSecurityPolicyApplyConfiguration) WithLabels(entries map[string]string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithLabels(entries map[string]string) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.Labels == nil && len(entries) > 0 { b.Labels = make(map[string]string, len(entries)) @@ -196,7 +196,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithLabels(entries map[string]stri // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Annotations field, // overwriting an existing map entries in Annotations field with the same key. -func (b *PodSecurityPolicyApplyConfiguration) WithAnnotations(entries map[string]string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithAnnotations(entries map[string]string) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.Annotations == nil && len(entries) > 0 { b.Annotations = make(map[string]string, len(entries)) @@ -210,7 +210,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithAnnotations(entries map[string // WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the OwnerReferences field. -func (b *PodSecurityPolicyApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { if values[i] == nil { @@ -224,7 +224,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithOwnerReferences(values ...*v1. // WithFinalizers adds the given value to the Finalizers field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the Finalizers field. -func (b *PodSecurityPolicyApplyConfiguration) WithFinalizers(values ...string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithFinalizers(values ...string) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { b.Finalizers = append(b.Finalizers, values[i]) @@ -232,7 +232,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithFinalizers(values ...string) * return b } -func (b *PodSecurityPolicyApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { +func (b *IPAddressApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { if b.ObjectMetaApplyConfiguration == nil { b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} } @@ -241,7 +241,7 @@ func (b *PodSecurityPolicyApplyConfiguration) ensureObjectMetaApplyConfiguration // WithSpec sets the Spec field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Spec field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithSpec(value *PodSecurityPolicySpecApplyConfiguration) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithSpec(value *IPAddressSpecApplyConfiguration) *IPAddressApplyConfiguration { b.Spec = value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddressspec.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddressspec.go new file mode 100644 index 0000000000..064963d691 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddressspec.go @@ -0,0 +1,39 @@ +/* +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 applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// IPAddressSpecApplyConfiguration represents an declarative configuration of the IPAddressSpec type for use +// with apply. +type IPAddressSpecApplyConfiguration struct { + ParentRef *ParentReferenceApplyConfiguration `json:"parentRef,omitempty"` +} + +// IPAddressSpecApplyConfiguration constructs an declarative configuration of the IPAddressSpec type for use with +// apply. +func IPAddressSpec() *IPAddressSpecApplyConfiguration { + return &IPAddressSpecApplyConfiguration{} +} + +// WithParentRef sets the ParentRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ParentRef field is set to the value of the last call. +func (b *IPAddressSpecApplyConfiguration) WithParentRef(value *ParentReferenceApplyConfiguration) *IPAddressSpecApplyConfiguration { + b.ParentRef = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/parentreference.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/parentreference.go new file mode 100644 index 0000000000..14b10b19ff --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/parentreference.go @@ -0,0 +1,79 @@ +/* +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 applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + types "k8s.io/apimachinery/pkg/types" +) + +// ParentReferenceApplyConfiguration represents an declarative configuration of the ParentReference type for use +// with apply. +type ParentReferenceApplyConfiguration struct { + Group *string `json:"group,omitempty"` + Resource *string `json:"resource,omitempty"` + Namespace *string `json:"namespace,omitempty"` + Name *string `json:"name,omitempty"` + UID *types.UID `json:"uid,omitempty"` +} + +// ParentReferenceApplyConfiguration constructs an declarative configuration of the ParentReference type for use with +// apply. +func ParentReference() *ParentReferenceApplyConfiguration { + return &ParentReferenceApplyConfiguration{} +} + +// WithGroup sets the Group field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Group field is set to the value of the last call. +func (b *ParentReferenceApplyConfiguration) WithGroup(value string) *ParentReferenceApplyConfiguration { + b.Group = &value + return b +} + +// WithResource sets the Resource field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Resource field is set to the value of the last call. +func (b *ParentReferenceApplyConfiguration) WithResource(value string) *ParentReferenceApplyConfiguration { + b.Resource = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ParentReferenceApplyConfiguration) WithNamespace(value string) *ParentReferenceApplyConfiguration { + b.Namespace = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ParentReferenceApplyConfiguration) WithName(value string) *ParentReferenceApplyConfiguration { + b.Name = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ParentReferenceApplyConfiguration) WithUID(value types.UID) *ParentReferenceApplyConfiguration { + b.UID = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/allocationresult.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/allocationresult.go similarity index 76% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/allocationresult.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/allocationresult.go index a2ad3adf1a..bc6078aa94 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/allocationresult.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/allocationresult.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( v1 "k8s.io/client-go/applyconfigurations/core/v1" @@ -25,7 +25,7 @@ import ( // AllocationResultApplyConfiguration represents an declarative configuration of the AllocationResult type for use // with apply. type AllocationResultApplyConfiguration struct { - ResourceHandle *string `json:"resourceHandle,omitempty"` + ResourceHandles []ResourceHandleApplyConfiguration `json:"resourceHandles,omitempty"` AvailableOnNodes *v1.NodeSelectorApplyConfiguration `json:"availableOnNodes,omitempty"` Shareable *bool `json:"shareable,omitempty"` } @@ -36,11 +36,16 @@ func AllocationResult() *AllocationResultApplyConfiguration { return &AllocationResultApplyConfiguration{} } -// WithResourceHandle sets the ResourceHandle field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ResourceHandle field is set to the value of the last call. -func (b *AllocationResultApplyConfiguration) WithResourceHandle(value string) *AllocationResultApplyConfiguration { - b.ResourceHandle = &value +// WithResourceHandles adds the given value to the ResourceHandles field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResourceHandles field. +func (b *AllocationResultApplyConfiguration) WithResourceHandles(values ...*ResourceHandleApplyConfiguration) *AllocationResultApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResourceHandles") + } + b.ResourceHandles = append(b.ResourceHandles, *values[i]) + } return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontext.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontext.go new file mode 100644 index 0000000000..1dfb6ff97b --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontext.go @@ -0,0 +1,258 @@ +/* +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 applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// PodSchedulingContextApplyConfiguration represents an declarative configuration of the PodSchedulingContext type for use +// with apply. +type PodSchedulingContextApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *PodSchedulingContextSpecApplyConfiguration `json:"spec,omitempty"` + Status *PodSchedulingContextStatusApplyConfiguration `json:"status,omitempty"` +} + +// PodSchedulingContext constructs an declarative configuration of the PodSchedulingContext type for use with +// apply. +func PodSchedulingContext(name, namespace string) *PodSchedulingContextApplyConfiguration { + b := &PodSchedulingContextApplyConfiguration{} + b.WithName(name) + b.WithNamespace(namespace) + b.WithKind("PodSchedulingContext") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b +} + +// ExtractPodSchedulingContext extracts the applied configuration owned by fieldManager from +// podSchedulingContext. If no managedFields are found in podSchedulingContext for fieldManager, a +// PodSchedulingContextApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// podSchedulingContext must be a unmodified PodSchedulingContext API object that was retrieved from the Kubernetes API. +// ExtractPodSchedulingContext provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractPodSchedulingContext(podSchedulingContext *resourcev1alpha2.PodSchedulingContext, fieldManager string) (*PodSchedulingContextApplyConfiguration, error) { + return extractPodSchedulingContext(podSchedulingContext, fieldManager, "") +} + +// ExtractPodSchedulingContextStatus is the same as ExtractPodSchedulingContext except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractPodSchedulingContextStatus(podSchedulingContext *resourcev1alpha2.PodSchedulingContext, fieldManager string) (*PodSchedulingContextApplyConfiguration, error) { + return extractPodSchedulingContext(podSchedulingContext, fieldManager, "status") +} + +func extractPodSchedulingContext(podSchedulingContext *resourcev1alpha2.PodSchedulingContext, fieldManager string, subresource string) (*PodSchedulingContextApplyConfiguration, error) { + b := &PodSchedulingContextApplyConfiguration{} + err := managedfields.ExtractInto(podSchedulingContext, internal.Parser().Type("io.k8s.api.resource.v1alpha2.PodSchedulingContext"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(podSchedulingContext.Name) + b.WithNamespace(podSchedulingContext.Namespace) + + b.WithKind("PodSchedulingContext") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithKind(value string) *PodSchedulingContextApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithAPIVersion(value string) *PodSchedulingContextApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithName(value string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithGenerateName(value string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithNamespace(value string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithUID(value types.UID) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithResourceVersion(value string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithGeneration(value int64) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithCreationTimestamp(value metav1.Time) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *PodSchedulingContextApplyConfiguration) WithLabels(entries map[string]string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *PodSchedulingContextApplyConfiguration) WithAnnotations(entries map[string]string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *PodSchedulingContextApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *PodSchedulingContextApplyConfiguration) WithFinalizers(values ...string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *PodSchedulingContextApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithSpec(value *PodSchedulingContextSpecApplyConfiguration) *PodSchedulingContextApplyConfiguration { + b.Spec = value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithStatus(value *PodSchedulingContextStatusApplyConfiguration) *PodSchedulingContextApplyConfiguration { + b.Status = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podschedulingspec.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextspec.go similarity index 67% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podschedulingspec.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextspec.go index 9fd3c1ee53..c95d3295e8 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podschedulingspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextspec.go @@ -16,25 +16,25 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 -// PodSchedulingSpecApplyConfiguration represents an declarative configuration of the PodSchedulingSpec type for use +// PodSchedulingContextSpecApplyConfiguration represents an declarative configuration of the PodSchedulingContextSpec type for use // with apply. -type PodSchedulingSpecApplyConfiguration struct { +type PodSchedulingContextSpecApplyConfiguration struct { SelectedNode *string `json:"selectedNode,omitempty"` PotentialNodes []string `json:"potentialNodes,omitempty"` } -// PodSchedulingSpecApplyConfiguration constructs an declarative configuration of the PodSchedulingSpec type for use with +// PodSchedulingContextSpecApplyConfiguration constructs an declarative configuration of the PodSchedulingContextSpec type for use with // apply. -func PodSchedulingSpec() *PodSchedulingSpecApplyConfiguration { - return &PodSchedulingSpecApplyConfiguration{} +func PodSchedulingContextSpec() *PodSchedulingContextSpecApplyConfiguration { + return &PodSchedulingContextSpecApplyConfiguration{} } // WithSelectedNode sets the SelectedNode field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the SelectedNode field is set to the value of the last call. -func (b *PodSchedulingSpecApplyConfiguration) WithSelectedNode(value string) *PodSchedulingSpecApplyConfiguration { +func (b *PodSchedulingContextSpecApplyConfiguration) WithSelectedNode(value string) *PodSchedulingContextSpecApplyConfiguration { b.SelectedNode = &value return b } @@ -42,7 +42,7 @@ func (b *PodSchedulingSpecApplyConfiguration) WithSelectedNode(value string) *Po // WithPotentialNodes adds the given value to the PotentialNodes field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the PotentialNodes field. -func (b *PodSchedulingSpecApplyConfiguration) WithPotentialNodes(values ...string) *PodSchedulingSpecApplyConfiguration { +func (b *PodSchedulingContextSpecApplyConfiguration) WithPotentialNodes(values ...string) *PodSchedulingContextSpecApplyConfiguration { for i := range values { b.PotentialNodes = append(b.PotentialNodes, values[i]) } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podschedulingstatus.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextstatus.go similarity index 64% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podschedulingstatus.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextstatus.go index 5744f6c3eb..a8b10b9a0e 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podschedulingstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextstatus.go @@ -16,24 +16,24 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 -// PodSchedulingStatusApplyConfiguration represents an declarative configuration of the PodSchedulingStatus type for use +// PodSchedulingContextStatusApplyConfiguration represents an declarative configuration of the PodSchedulingContextStatus type for use // with apply. -type PodSchedulingStatusApplyConfiguration struct { +type PodSchedulingContextStatusApplyConfiguration struct { ResourceClaims []ResourceClaimSchedulingStatusApplyConfiguration `json:"resourceClaims,omitempty"` } -// PodSchedulingStatusApplyConfiguration constructs an declarative configuration of the PodSchedulingStatus type for use with +// PodSchedulingContextStatusApplyConfiguration constructs an declarative configuration of the PodSchedulingContextStatus type for use with // apply. -func PodSchedulingStatus() *PodSchedulingStatusApplyConfiguration { - return &PodSchedulingStatusApplyConfiguration{} +func PodSchedulingContextStatus() *PodSchedulingContextStatusApplyConfiguration { + return &PodSchedulingContextStatusApplyConfiguration{} } // WithResourceClaims adds the given value to the ResourceClaims field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the ResourceClaims field. -func (b *PodSchedulingStatusApplyConfiguration) WithResourceClaims(values ...*ResourceClaimSchedulingStatusApplyConfiguration) *PodSchedulingStatusApplyConfiguration { +func (b *PodSchedulingContextStatusApplyConfiguration) WithResourceClaims(values ...*ResourceClaimSchedulingStatusApplyConfiguration) *PodSchedulingContextStatusApplyConfiguration { for i := range values { if values[i] == nil { panic("nil value passed to WithResourceClaims") diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaim.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaim.go similarity index 96% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaim.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaim.go index f94811a9b1..6c219f837b 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaim.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaim.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" managedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -43,7 +43,7 @@ func ResourceClaim(name, namespace string) *ResourceClaimApplyConfiguration { b.WithName(name) b.WithNamespace(namespace) b.WithKind("ResourceClaim") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithAPIVersion("resource.k8s.io/v1alpha2") return b } @@ -58,20 +58,20 @@ func ResourceClaim(name, namespace string) *ResourceClaimApplyConfiguration { // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. // Experimental! -func ExtractResourceClaim(resourceClaim *resourcev1alpha1.ResourceClaim, fieldManager string) (*ResourceClaimApplyConfiguration, error) { +func ExtractResourceClaim(resourceClaim *resourcev1alpha2.ResourceClaim, fieldManager string) (*ResourceClaimApplyConfiguration, error) { return extractResourceClaim(resourceClaim, fieldManager, "") } // ExtractResourceClaimStatus is the same as ExtractResourceClaim except // that it extracts the status subresource applied configuration. // Experimental! -func ExtractResourceClaimStatus(resourceClaim *resourcev1alpha1.ResourceClaim, fieldManager string) (*ResourceClaimApplyConfiguration, error) { +func ExtractResourceClaimStatus(resourceClaim *resourcev1alpha2.ResourceClaim, fieldManager string) (*ResourceClaimApplyConfiguration, error) { return extractResourceClaim(resourceClaim, fieldManager, "status") } -func extractResourceClaim(resourceClaim *resourcev1alpha1.ResourceClaim, fieldManager string, subresource string) (*ResourceClaimApplyConfiguration, error) { +func extractResourceClaim(resourceClaim *resourcev1alpha2.ResourceClaim, fieldManager string, subresource string) (*ResourceClaimApplyConfiguration, error) { b := &ResourceClaimApplyConfiguration{} - err := managedfields.ExtractInto(resourceClaim, internal.Parser().Type("io.k8s.api.resource.v1alpha1.ResourceClaim"), fieldManager, b, subresource) + err := managedfields.ExtractInto(resourceClaim, internal.Parser().Type("io.k8s.api.resource.v1alpha2.ResourceClaim"), fieldManager, b, subresource) if err != nil { return nil, err } @@ -79,7 +79,7 @@ func extractResourceClaim(resourceClaim *resourcev1alpha1.ResourceClaim, fieldMa b.WithNamespace(resourceClaim.Namespace) b.WithKind("ResourceClaim") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithAPIVersion("resource.k8s.io/v1alpha2") return b, nil } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimconsumerreference.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimconsumerreference.go similarity index 99% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimconsumerreference.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimconsumerreference.go index 477099cd7a..41bb9e9a14 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimconsumerreference.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimconsumerreference.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( types "k8s.io/apimachinery/pkg/types" diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimparametersreference.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimparametersreference.go similarity index 99% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimparametersreference.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimparametersreference.go index d7b25d75eb..27820ede60 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimparametersreference.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimparametersreference.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 // ResourceClaimParametersReferenceApplyConfiguration represents an declarative configuration of the ResourceClaimParametersReference type for use // with apply. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimschedulingstatus.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimschedulingstatus.go similarity index 99% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimschedulingstatus.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimschedulingstatus.go index 35ff34abab..e74679aed3 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimschedulingstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimschedulingstatus.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 // ResourceClaimSchedulingStatusApplyConfiguration represents an declarative configuration of the ResourceClaimSchedulingStatus type for use // with apply. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimspec.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimspec.go similarity index 93% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimspec.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimspec.go index d326190462..0c73e64e9e 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimspec.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" ) // ResourceClaimSpecApplyConfiguration represents an declarative configuration of the ResourceClaimSpec type for use @@ -27,7 +27,7 @@ import ( type ResourceClaimSpecApplyConfiguration struct { ResourceClassName *string `json:"resourceClassName,omitempty"` ParametersRef *ResourceClaimParametersReferenceApplyConfiguration `json:"parametersRef,omitempty"` - AllocationMode *resourcev1alpha1.AllocationMode `json:"allocationMode,omitempty"` + AllocationMode *resourcev1alpha2.AllocationMode `json:"allocationMode,omitempty"` } // ResourceClaimSpecApplyConfiguration constructs an declarative configuration of the ResourceClaimSpec type for use with @@ -55,7 +55,7 @@ func (b *ResourceClaimSpecApplyConfiguration) WithParametersRef(value *ResourceC // WithAllocationMode sets the AllocationMode field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the AllocationMode field is set to the value of the last call. -func (b *ResourceClaimSpecApplyConfiguration) WithAllocationMode(value resourcev1alpha1.AllocationMode) *ResourceClaimSpecApplyConfiguration { +func (b *ResourceClaimSpecApplyConfiguration) WithAllocationMode(value resourcev1alpha2.AllocationMode) *ResourceClaimSpecApplyConfiguration { b.AllocationMode = &value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimstatus.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimstatus.go similarity index 99% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimstatus.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimstatus.go index e2283f8b07..c6fa610906 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimstatus.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 // ResourceClaimStatusApplyConfiguration represents an declarative configuration of the ResourceClaimStatus type for use // with apply. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimtemplate.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplate.go similarity index 96% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimtemplate.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplate.go index e3c602cb65..fc2209b8f0 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimtemplate.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplate.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" managedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -42,7 +42,7 @@ func ResourceClaimTemplate(name, namespace string) *ResourceClaimTemplateApplyCo b.WithName(name) b.WithNamespace(namespace) b.WithKind("ResourceClaimTemplate") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithAPIVersion("resource.k8s.io/v1alpha2") return b } @@ -57,20 +57,20 @@ func ResourceClaimTemplate(name, namespace string) *ResourceClaimTemplateApplyCo // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. // Experimental! -func ExtractResourceClaimTemplate(resourceClaimTemplate *resourcev1alpha1.ResourceClaimTemplate, fieldManager string) (*ResourceClaimTemplateApplyConfiguration, error) { +func ExtractResourceClaimTemplate(resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplate, fieldManager string) (*ResourceClaimTemplateApplyConfiguration, error) { return extractResourceClaimTemplate(resourceClaimTemplate, fieldManager, "") } // ExtractResourceClaimTemplateStatus is the same as ExtractResourceClaimTemplate except // that it extracts the status subresource applied configuration. // Experimental! -func ExtractResourceClaimTemplateStatus(resourceClaimTemplate *resourcev1alpha1.ResourceClaimTemplate, fieldManager string) (*ResourceClaimTemplateApplyConfiguration, error) { +func ExtractResourceClaimTemplateStatus(resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplate, fieldManager string) (*ResourceClaimTemplateApplyConfiguration, error) { return extractResourceClaimTemplate(resourceClaimTemplate, fieldManager, "status") } -func extractResourceClaimTemplate(resourceClaimTemplate *resourcev1alpha1.ResourceClaimTemplate, fieldManager string, subresource string) (*ResourceClaimTemplateApplyConfiguration, error) { +func extractResourceClaimTemplate(resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplate, fieldManager string, subresource string) (*ResourceClaimTemplateApplyConfiguration, error) { b := &ResourceClaimTemplateApplyConfiguration{} - err := managedfields.ExtractInto(resourceClaimTemplate, internal.Parser().Type("io.k8s.api.resource.v1alpha1.ResourceClaimTemplate"), fieldManager, b, subresource) + err := managedfields.ExtractInto(resourceClaimTemplate, internal.Parser().Type("io.k8s.api.resource.v1alpha2.ResourceClaimTemplate"), fieldManager, b, subresource) if err != nil { return nil, err } @@ -78,7 +78,7 @@ func extractResourceClaimTemplate(resourceClaimTemplate *resourcev1alpha1.Resour b.WithNamespace(resourceClaimTemplate.Namespace) b.WithKind("ResourceClaimTemplate") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithAPIVersion("resource.k8s.io/v1alpha2") return b, nil } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimtemplatespec.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplatespec.go similarity index 99% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimtemplatespec.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplatespec.go index 88058e066e..2f38ea0366 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimtemplatespec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplatespec.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclass.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclass.go similarity index 96% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclass.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclass.go index 5f980acdb1..724c9e88e0 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclass.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclass.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" managedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -44,7 +44,7 @@ func ResourceClass(name string) *ResourceClassApplyConfiguration { b := &ResourceClassApplyConfiguration{} b.WithName(name) b.WithKind("ResourceClass") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithAPIVersion("resource.k8s.io/v1alpha2") return b } @@ -59,27 +59,27 @@ func ResourceClass(name string) *ResourceClassApplyConfiguration { // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. // Experimental! -func ExtractResourceClass(resourceClass *resourcev1alpha1.ResourceClass, fieldManager string) (*ResourceClassApplyConfiguration, error) { +func ExtractResourceClass(resourceClass *resourcev1alpha2.ResourceClass, fieldManager string) (*ResourceClassApplyConfiguration, error) { return extractResourceClass(resourceClass, fieldManager, "") } // ExtractResourceClassStatus is the same as ExtractResourceClass except // that it extracts the status subresource applied configuration. // Experimental! -func ExtractResourceClassStatus(resourceClass *resourcev1alpha1.ResourceClass, fieldManager string) (*ResourceClassApplyConfiguration, error) { +func ExtractResourceClassStatus(resourceClass *resourcev1alpha2.ResourceClass, fieldManager string) (*ResourceClassApplyConfiguration, error) { return extractResourceClass(resourceClass, fieldManager, "status") } -func extractResourceClass(resourceClass *resourcev1alpha1.ResourceClass, fieldManager string, subresource string) (*ResourceClassApplyConfiguration, error) { +func extractResourceClass(resourceClass *resourcev1alpha2.ResourceClass, fieldManager string, subresource string) (*ResourceClassApplyConfiguration, error) { b := &ResourceClassApplyConfiguration{} - err := managedfields.ExtractInto(resourceClass, internal.Parser().Type("io.k8s.api.resource.v1alpha1.ResourceClass"), fieldManager, b, subresource) + err := managedfields.ExtractInto(resourceClass, internal.Parser().Type("io.k8s.api.resource.v1alpha2.ResourceClass"), fieldManager, b, subresource) if err != nil { return nil, err } b.WithName(resourceClass.Name) b.WithKind("ResourceClass") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithAPIVersion("resource.k8s.io/v1alpha2") return b, nil } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclassparametersreference.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclassparametersreference.go similarity index 99% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclassparametersreference.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclassparametersreference.go index b03a9a6da4..d67e4d3977 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclassparametersreference.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclassparametersreference.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 // ResourceClassParametersReferenceApplyConfiguration represents an declarative configuration of the ResourceClassParametersReference type for use // with apply. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcehandle.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcehandle.go new file mode 100644 index 0000000000..028cbaa1a7 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcehandle.go @@ -0,0 +1,48 @@ +/* +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 applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// ResourceHandleApplyConfiguration represents an declarative configuration of the ResourceHandle type for use +// with apply. +type ResourceHandleApplyConfiguration struct { + DriverName *string `json:"driverName,omitempty"` + Data *string `json:"data,omitempty"` +} + +// ResourceHandleApplyConfiguration constructs an declarative configuration of the ResourceHandle type for use with +// apply. +func ResourceHandle() *ResourceHandleApplyConfiguration { + return &ResourceHandleApplyConfiguration{} +} + +// WithDriverName sets the DriverName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DriverName field is set to the value of the last call. +func (b *ResourceHandleApplyConfiguration) WithDriverName(value string) *ResourceHandleApplyConfiguration { + b.DriverName = &value + return b +} + +// WithData sets the Data field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Data field is set to the value of the last call. +func (b *ResourceHandleApplyConfiguration) WithData(value string) *ResourceHandleApplyConfiguration { + b.Data = &value + return b +} diff --git a/vendor/k8s.io/client-go/discovery/aggregated_discovery.go b/vendor/k8s.io/client-go/discovery/aggregated_discovery.go index 033a4c8fc3..7470259dc8 100644 --- a/vendor/k8s.io/client-go/discovery/aggregated_discovery.go +++ b/vendor/k8s.io/client-go/discovery/aggregated_discovery.go @@ -24,19 +24,36 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) +// StaleGroupVersionError encasulates failed GroupVersion marked "stale" +// in the returned AggregatedDiscovery format. +type StaleGroupVersionError struct { + gv schema.GroupVersion +} + +func (s StaleGroupVersionError) Error() string { + return fmt.Sprintf("stale GroupVersion discovery: %v", s.gv) +} + // SplitGroupsAndResources transforms "aggregated" discovery top-level structure into // the previous "unaggregated" discovery groups and resources. -func SplitGroupsAndResources(aggregatedGroups apidiscovery.APIGroupDiscoveryList) (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList) { +func SplitGroupsAndResources(aggregatedGroups apidiscovery.APIGroupDiscoveryList) ( + *metav1.APIGroupList, + map[schema.GroupVersion]*metav1.APIResourceList, + map[schema.GroupVersion]error) { // Aggregated group list will contain the entirety of discovery, including - // groups, versions, and resources. + // groups, versions, and resources. GroupVersions marked "stale" are failed. groups := []*metav1.APIGroup{} + failedGVs := map[schema.GroupVersion]error{} resourcesByGV := map[schema.GroupVersion]*metav1.APIResourceList{} for _, aggGroup := range aggregatedGroups.Items { - group, resources := convertAPIGroup(aggGroup) + group, resources, failed := convertAPIGroup(aggGroup) groups = append(groups, group) for gv, resourceList := range resources { resourcesByGV[gv] = resourceList } + for gv, err := range failed { + failedGVs[gv] = err + } } // Transform slice of groups to group list before returning. groupList := &metav1.APIGroupList{} @@ -44,65 +61,94 @@ func SplitGroupsAndResources(aggregatedGroups apidiscovery.APIGroupDiscoveryList for _, group := range groups { groupList.Groups = append(groupList.Groups, *group) } - return groupList, resourcesByGV + return groupList, resourcesByGV, failedGVs } // convertAPIGroup tranforms an "aggregated" APIGroupDiscovery to an "legacy" APIGroup, // also returning the map of APIResourceList for resources within GroupVersions. -func convertAPIGroup(g apidiscovery.APIGroupDiscovery) (*metav1.APIGroup, map[schema.GroupVersion]*metav1.APIResourceList) { +func convertAPIGroup(g apidiscovery.APIGroupDiscovery) ( + *metav1.APIGroup, + map[schema.GroupVersion]*metav1.APIResourceList, + map[schema.GroupVersion]error) { // Iterate through versions to convert to group and resources. group := &metav1.APIGroup{} gvResources := map[schema.GroupVersion]*metav1.APIResourceList{} + failedGVs := map[schema.GroupVersion]error{} group.Name = g.ObjectMeta.Name - for i, v := range g.Versions { - version := metav1.GroupVersionForDiscovery{} + for _, v := range g.Versions { gv := schema.GroupVersion{Group: g.Name, Version: v.Version} + if v.Freshness == apidiscovery.DiscoveryFreshnessStale { + failedGVs[gv] = StaleGroupVersionError{gv: gv} + continue + } + version := metav1.GroupVersionForDiscovery{} version.GroupVersion = gv.String() version.Version = v.Version group.Versions = append(group.Versions, version) - if i == 0 { + // PreferredVersion is first non-stale Version + if group.PreferredVersion == (metav1.GroupVersionForDiscovery{}) { group.PreferredVersion = version } resourceList := &metav1.APIResourceList{} resourceList.GroupVersion = gv.String() for _, r := range v.Resources { - resource := convertAPIResource(r) - resourceList.APIResources = append(resourceList.APIResources, resource) + resource, err := convertAPIResource(r) + if err == nil { + resourceList.APIResources = append(resourceList.APIResources, resource) + } // Subresources field in new format get transformed into full APIResources. + // It is possible a partial result with an error was returned to be used + // as the parent resource for the subresource. for _, subresource := range r.Subresources { - sr := convertAPISubresource(resource, subresource) - resourceList.APIResources = append(resourceList.APIResources, sr) + sr, err := convertAPISubresource(resource, subresource) + if err == nil { + resourceList.APIResources = append(resourceList.APIResources, sr) + } } } gvResources[gv] = resourceList } - return group, gvResources + return group, gvResources, failedGVs } -// convertAPIResource tranforms a APIResourceDiscovery to an APIResource. -func convertAPIResource(in apidiscovery.APIResourceDiscovery) metav1.APIResource { - return metav1.APIResource{ +// convertAPIResource tranforms a APIResourceDiscovery to an APIResource. We are +// resilient to missing GVK, since this resource might be the parent resource +// for a subresource. If the parent is missing a GVK, it is not returned in +// discovery, and the subresource MUST have the GVK. +func convertAPIResource(in apidiscovery.APIResourceDiscovery) (metav1.APIResource, error) { + result := metav1.APIResource{ Name: in.Resource, SingularName: in.SingularResource, Namespaced: in.Scope == apidiscovery.ScopeNamespace, - Group: in.ResponseKind.Group, - Version: in.ResponseKind.Version, - Kind: in.ResponseKind.Kind, Verbs: in.Verbs, ShortNames: in.ShortNames, Categories: in.Categories, } + var err error + if in.ResponseKind != nil { + result.Group = in.ResponseKind.Group + result.Version = in.ResponseKind.Version + result.Kind = in.ResponseKind.Kind + } else { + err = fmt.Errorf("discovery resource %s missing GVK", in.Resource) + } + // Can return partial result with error, which can be the parent for a + // subresource. Do not add this result to the returned discovery resources. + return result, err } // convertAPISubresource tranforms a APISubresourceDiscovery to an APIResource. -func convertAPISubresource(parent metav1.APIResource, in apidiscovery.APISubresourceDiscovery) metav1.APIResource { - return metav1.APIResource{ - Name: fmt.Sprintf("%s/%s", parent.Name, in.Subresource), - SingularName: parent.SingularName, - Namespaced: parent.Namespaced, - Group: in.ResponseKind.Group, - Version: in.ResponseKind.Version, - Kind: in.ResponseKind.Kind, - Verbs: in.Verbs, +func convertAPISubresource(parent metav1.APIResource, in apidiscovery.APISubresourceDiscovery) (metav1.APIResource, error) { + result := metav1.APIResource{} + if in.ResponseKind == nil { + return result, fmt.Errorf("subresource %s/%s missing GVK", parent.Name, in.Subresource) } + result.Name = fmt.Sprintf("%s/%s", parent.Name, in.Subresource) + result.SingularName = parent.SingularName + result.Namespaced = parent.Namespaced + result.Group = in.ResponseKind.Group + result.Version = in.ResponseKind.Version + result.Kind = in.ResponseKind.Kind + result.Verbs = in.Verbs + return result, nil } diff --git a/vendor/k8s.io/client-go/discovery/cached/memory/memcache.go b/vendor/k8s.io/client-go/discovery/cached/memory/memcache.go index 0a41018474..9143ce00ab 100644 --- a/vendor/k8s.io/client-go/discovery/cached/memory/memcache.go +++ b/vendor/k8s.io/client-go/discovery/cached/memory/memcache.go @@ -33,6 +33,7 @@ import ( "k8s.io/client-go/openapi" cachedopenapi "k8s.io/client-go/openapi/cached" restclient "k8s.io/client-go/rest" + "k8s.io/klog/v2" ) type cacheEntry struct { @@ -61,6 +62,15 @@ var ( ErrCacheNotFound = errors.New("not found") ) +// Server returning empty ResourceList for Group/Version. +type emptyResponseError struct { + gv string +} + +func (e *emptyResponseError) Error() string { + return fmt.Sprintf("received empty response for: %s", e.gv) +} + var _ discovery.CachedDiscoveryInterface = &memCacheClient{} // isTransientConnectionError checks whether given error is "Connection refused" or @@ -103,7 +113,13 @@ func (d *memCacheClient) ServerResourcesForGroupVersion(groupVersion string) (*m if cachedVal.err != nil && isTransientError(cachedVal.err) { r, err := d.serverResourcesForGroupVersion(groupVersion) if err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't get resource list for %v: %v", groupVersion, err)) + // Don't log "empty response" as an error; it is a common response for metrics. + if _, emptyErr := err.(*emptyResponseError); emptyErr { + // Log at same verbosity as disk cache. + klog.V(3).Infof("%v", err) + } else { + utilruntime.HandleError(fmt.Errorf("couldn't get resource list for %v: %v", groupVersion, err)) + } } cachedVal = &cacheEntry{r, err} d.groupToServerResources[groupVersion] = cachedVal @@ -120,32 +136,38 @@ func (d *memCacheClient) ServerGroupsAndResources() ([]*metav1.APIGroup, []*meta // GroupsAndMaybeResources returns the list of APIGroups, and possibly the map of group/version // to resources. The returned groups will never be nil, but the resources map can be nil // if there are no cached resources. -func (d *memCacheClient) GroupsAndMaybeResources() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, error) { +func (d *memCacheClient) GroupsAndMaybeResources() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, map[schema.GroupVersion]error, error) { d.lock.Lock() defer d.lock.Unlock() if !d.cacheValid { if err := d.refreshLocked(); err != nil { - return nil, nil, err + return nil, nil, nil, err } } // Build the resourceList from the cache? var resourcesMap map[schema.GroupVersion]*metav1.APIResourceList + var failedGVs map[schema.GroupVersion]error if d.receivedAggregatedDiscovery && len(d.groupToServerResources) > 0 { resourcesMap = map[schema.GroupVersion]*metav1.APIResourceList{} + failedGVs = map[schema.GroupVersion]error{} for gv, cacheEntry := range d.groupToServerResources { groupVersion, err := schema.ParseGroupVersion(gv) if err != nil { - return nil, nil, fmt.Errorf("failed to parse group version (%v): %v", gv, err) + return nil, nil, nil, fmt.Errorf("failed to parse group version (%v): %v", gv, err) + } + if cacheEntry.err != nil { + failedGVs[groupVersion] = cacheEntry.err + } else { + resourcesMap[groupVersion] = cacheEntry.resourceList } - resourcesMap[groupVersion] = cacheEntry.resourceList } } - return d.groupList, resourcesMap, nil + return d.groupList, resourcesMap, failedGVs, nil } func (d *memCacheClient) ServerGroups() (*metav1.APIGroupList, error) { - groups, _, err := d.GroupsAndMaybeResources() + groups, _, _, err := d.GroupsAndMaybeResources() if err != nil { return nil, err } @@ -219,7 +241,8 @@ func (d *memCacheClient) refreshLocked() error { if ad, ok := d.delegate.(discovery.AggregatedDiscoveryInterface); ok { var resources map[schema.GroupVersion]*metav1.APIResourceList - gl, resources, err = ad.GroupsAndMaybeResources() + var failedGVs map[schema.GroupVersion]error + gl, resources, failedGVs, err = ad.GroupsAndMaybeResources() if resources != nil && err == nil { // Cache the resources. d.groupToServerResources = map[string]*cacheEntry{} @@ -227,6 +250,10 @@ func (d *memCacheClient) refreshLocked() error { for gv, resources := range resources { d.groupToServerResources[gv.String()] = &cacheEntry{resources, nil} } + // Cache GroupVersion discovery errors + for gv, err := range failedGVs { + d.groupToServerResources[gv.String()] = &cacheEntry{nil, err} + } d.receivedAggregatedDiscovery = true d.cacheValid = true return nil @@ -252,7 +279,13 @@ func (d *memCacheClient) refreshLocked() error { r, err := d.serverResourcesForGroupVersion(gv) if err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't get resource list for %v: %v", gv, err)) + // Don't log "empty response" as an error; it is a common response for metrics. + if _, emptyErr := err.(*emptyResponseError); emptyErr { + // Log at same verbosity as disk cache. + klog.V(3).Infof("%v", err) + } else { + utilruntime.HandleError(fmt.Errorf("couldn't get resource list for %v: %v", gv, err)) + } } resultLock.Lock() @@ -274,7 +307,7 @@ func (d *memCacheClient) serverResourcesForGroupVersion(groupVersion string) (*m return r, err } if len(r.APIResources) == 0 { - return r, fmt.Errorf("Got empty response for: %v", groupVersion) + return r, &emptyResponseError{gv: groupVersion} } return r, nil } diff --git a/vendor/k8s.io/client-go/discovery/discovery_client.go b/vendor/k8s.io/client-go/discovery/discovery_client.go index 9025e888ec..641568008b 100644 --- a/vendor/k8s.io/client-go/discovery/discovery_client.go +++ b/vendor/k8s.io/client-go/discovery/discovery_client.go @@ -86,7 +86,7 @@ type DiscoveryInterface interface { type AggregatedDiscoveryInterface interface { DiscoveryInterface - GroupsAndMaybeResources() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, error) + GroupsAndMaybeResources() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, map[schema.GroupVersion]error, error) } // CachedDiscoveryInterface is a DiscoveryInterface with cache invalidation and freshness. @@ -186,18 +186,23 @@ func apiVersionsToAPIGroup(apiVersions *metav1.APIVersions) (apiGroup metav1.API // and resources from /api and /apis (either aggregated or not). Legacy groups // must be ordered first. The server will either return both endpoints (/api, /apis) // as aggregated discovery format or legacy format. For safety, resources will only -// be returned if both endpoints returned resources. -func (d *DiscoveryClient) GroupsAndMaybeResources() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, error) { +// be returned if both endpoints returned resources. Returned "failedGVs" can be +// empty, but will only be nil in the case an error is returned. +func (d *DiscoveryClient) GroupsAndMaybeResources() ( + *metav1.APIGroupList, + map[schema.GroupVersion]*metav1.APIResourceList, + map[schema.GroupVersion]error, + error) { // Legacy group ordered first (there is only one -- core/v1 group). Returned groups must // be non-nil, but it could be empty. Returned resources, apiResources map could be nil. - groups, resources, err := d.downloadLegacy() + groups, resources, failedGVs, err := d.downloadLegacy() if err != nil { - return nil, nil, err + return nil, nil, nil, err } // Discovery groups and (possibly) resources downloaded from /apis. - apiGroups, apiResources, aerr := d.downloadAPIs() - if err != nil { - return nil, nil, aerr + apiGroups, apiResources, failedApisGVs, aerr := d.downloadAPIs() + if aerr != nil { + return nil, nil, nil, aerr } // Merge apis groups into the legacy groups. for _, group := range apiGroups.Groups { @@ -211,14 +216,23 @@ func (d *DiscoveryClient) GroupsAndMaybeResources() (*metav1.APIGroupList, map[s } else if resources != nil { resources = nil } - return groups, resources, err + // Merge failed GroupVersions from /api and /apis + for gv, err := range failedApisGVs { + failedGVs[gv] = err + } + return groups, resources, failedGVs, err } // downloadLegacy returns the discovery groups and possibly resources // for the legacy v1 GVR at /api, or an error if one occurred. It is // possible for the resource map to be nil if the server returned -// the unaggregated discovery. -func (d *DiscoveryClient) downloadLegacy() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, error) { +// the unaggregated discovery. Returned "failedGVs" can be empty, but +// will only be nil in the case of a returned error. +func (d *DiscoveryClient) downloadLegacy() ( + *metav1.APIGroupList, + map[schema.GroupVersion]*metav1.APIResourceList, + map[schema.GroupVersion]error, + error) { accept := acceptDiscoveryFormats if d.UseLegacyDiscovery { accept = AcceptV1 @@ -230,16 +244,19 @@ func (d *DiscoveryClient) downloadLegacy() (*metav1.APIGroupList, map[schema.Gro Do(context.TODO()). ContentType(&responseContentType). Raw() - // Special error handling for 403 or 404 to be compatible with older v1.0 servers. - // Return empty group list to be merged with /apis. - if err != nil && !errors.IsNotFound(err) && !errors.IsForbidden(err) { - return nil, nil, err - } - if err != nil && (errors.IsNotFound(err) || errors.IsForbidden(err)) { - return &metav1.APIGroupList{}, nil, nil + apiGroupList := &metav1.APIGroupList{} + failedGVs := map[schema.GroupVersion]error{} + if err != nil { + // Tolerate 404, since aggregated api servers can return it. + if errors.IsNotFound(err) { + // Return empty structures and no error. + emptyGVMap := map[schema.GroupVersion]*metav1.APIResourceList{} + return apiGroupList, emptyGVMap, failedGVs, nil + } else { + return nil, nil, nil, err + } } - apiGroupList := &metav1.APIGroupList{} var resourcesByGV map[schema.GroupVersion]*metav1.APIResourceList // Switch on content-type server responded with: aggregated or unaggregated. switch responseContentType { @@ -247,7 +264,7 @@ func (d *DiscoveryClient) downloadLegacy() (*metav1.APIGroupList, map[schema.Gro var v metav1.APIVersions err = json.Unmarshal(body, &v) if err != nil { - return nil, nil, err + return nil, nil, nil, err } apiGroup := metav1.APIGroup{} if len(v.Versions) != 0 { @@ -258,20 +275,25 @@ func (d *DiscoveryClient) downloadLegacy() (*metav1.APIGroupList, map[schema.Gro var aggregatedDiscovery apidiscovery.APIGroupDiscoveryList err = json.Unmarshal(body, &aggregatedDiscovery) if err != nil { - return nil, nil, err + return nil, nil, nil, err } - apiGroupList, resourcesByGV = SplitGroupsAndResources(aggregatedDiscovery) + apiGroupList, resourcesByGV, failedGVs = SplitGroupsAndResources(aggregatedDiscovery) default: - return nil, nil, fmt.Errorf("Unknown discovery response content-type: %s", responseContentType) + return nil, nil, nil, fmt.Errorf("Unknown discovery response content-type: %s", responseContentType) } - return apiGroupList, resourcesByGV, nil + return apiGroupList, resourcesByGV, failedGVs, nil } // downloadAPIs returns the discovery groups and (if aggregated format) the // discovery resources. The returned groups will always exist, but the -// resources map may be nil. -func (d *DiscoveryClient) downloadAPIs() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, error) { +// resources map may be nil. Returned "failedGVs" can be empty, but will +// only be nil in the case of a returned error. +func (d *DiscoveryClient) downloadAPIs() ( + *metav1.APIGroupList, + map[schema.GroupVersion]*metav1.APIResourceList, + map[schema.GroupVersion]error, + error) { accept := acceptDiscoveryFormats if d.UseLegacyDiscovery { accept = AcceptV1 @@ -283,42 +305,38 @@ func (d *DiscoveryClient) downloadAPIs() (*metav1.APIGroupList, map[schema.Group Do(context.TODO()). ContentType(&responseContentType). Raw() - // Special error handling for 403 or 404 to be compatible with older v1.0 servers. - // Return empty group list to be merged with /api. - if err != nil && !errors.IsNotFound(err) && !errors.IsForbidden(err) { - return nil, nil, err - } - if err != nil && (errors.IsNotFound(err) || errors.IsForbidden(err)) { - return &metav1.APIGroupList{}, nil, nil + if err != nil { + return nil, nil, nil, err } apiGroupList := &metav1.APIGroupList{} + failedGVs := map[schema.GroupVersion]error{} var resourcesByGV map[schema.GroupVersion]*metav1.APIResourceList // Switch on content-type server responded with: aggregated or unaggregated. switch responseContentType { case AcceptV1: err = json.Unmarshal(body, apiGroupList) if err != nil { - return nil, nil, err + return nil, nil, nil, err } case AcceptV2Beta1: var aggregatedDiscovery apidiscovery.APIGroupDiscoveryList err = json.Unmarshal(body, &aggregatedDiscovery) if err != nil { - return nil, nil, err + return nil, nil, nil, err } - apiGroupList, resourcesByGV = SplitGroupsAndResources(aggregatedDiscovery) + apiGroupList, resourcesByGV, failedGVs = SplitGroupsAndResources(aggregatedDiscovery) default: - return nil, nil, fmt.Errorf("Unknown discovery response content-type: %s", responseContentType) + return nil, nil, nil, fmt.Errorf("Unknown discovery response content-type: %s", responseContentType) } - return apiGroupList, resourcesByGV, nil + return apiGroupList, resourcesByGV, failedGVs, nil } // ServerGroups returns the supported groups, with information like supported versions and the // preferred version. func (d *DiscoveryClient) ServerGroups() (*metav1.APIGroupList, error) { - groups, _, err := d.GroupsAndMaybeResources() + groups, _, _, err := d.GroupsAndMaybeResources() if err != nil { return nil, err } @@ -341,8 +359,10 @@ func (d *DiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (r } err = d.restClient.Get().AbsPath(url.String()).Do(context.TODO()).Into(resources) if err != nil { - // ignore 403 or 404 error to be compatible with an v1.0 server. - if groupVersion == "v1" && (errors.IsNotFound(err) || errors.IsForbidden(err)) { + // Tolerate core/v1 not found response by returning empty resource list; + // this probably should not happen. But we should verify all callers are + // not depending on this toleration before removal. + if groupVersion == "v1" && errors.IsNotFound(err) { return resources, nil } return nil, err @@ -383,13 +403,14 @@ func IsGroupDiscoveryFailedError(err error) bool { func ServerGroupsAndResources(d DiscoveryInterface) ([]*metav1.APIGroup, []*metav1.APIResourceList, error) { var sgs *metav1.APIGroupList var resources []*metav1.APIResourceList + var failedGVs map[schema.GroupVersion]error var err error // If the passed discovery object implements the wider AggregatedDiscoveryInterface, // then attempt to retrieve aggregated discovery with both groups and the resources. if ad, ok := d.(AggregatedDiscoveryInterface); ok { var resourcesByGV map[schema.GroupVersion]*metav1.APIResourceList - sgs, resourcesByGV, err = ad.GroupsAndMaybeResources() + sgs, resourcesByGV, failedGVs, err = ad.GroupsAndMaybeResources() for _, resourceList := range resourcesByGV { resources = append(resources, resourceList) } @@ -404,8 +425,15 @@ func ServerGroupsAndResources(d DiscoveryInterface) ([]*metav1.APIGroup, []*meta for i := range sgs.Groups { resultGroups = append(resultGroups, &sgs.Groups[i]) } + // resources is non-nil if aggregated discovery succeeded. if resources != nil { - return resultGroups, resources, nil + // Any stale Group/Versions returned by aggregated discovery + // must be surfaced to the caller as failed Group/Versions. + var ferr error + if len(failedGVs) > 0 { + ferr = &ErrGroupDiscoveryFailed{Groups: failedGVs} + } + return resultGroups, resources, ferr } groupVersionResources, failedGroups := fetchGroupVersionResources(d, sgs) @@ -436,16 +464,18 @@ func ServerPreferredResources(d DiscoveryInterface) ([]*metav1.APIResourceList, var err error // If the passed discovery object implements the wider AggregatedDiscoveryInterface, - // then it is attempt to retrieve both the groups and the resources. + // then it is attempt to retrieve both the groups and the resources. "failedGroups" + // are Group/Versions returned as stale in AggregatedDiscovery format. ad, ok := d.(AggregatedDiscoveryInterface) if ok { - serverGroupList, groupVersionResources, err = ad.GroupsAndMaybeResources() + serverGroupList, groupVersionResources, failedGroups, err = ad.GroupsAndMaybeResources() } else { serverGroupList, err = d.ServerGroups() } if err != nil { return nil, err } + // Non-aggregated discovery must fetch resources from Groups. if groupVersionResources == nil { groupVersionResources, failedGroups = fetchGroupVersionResources(d, serverGroupList) } diff --git a/vendor/k8s.io/client-go/discovery/fake/discovery.go b/vendor/k8s.io/client-go/discovery/fake/discovery.go index c78c256ef7..d234db893d 100644 --- a/vendor/k8s.io/client-go/discovery/fake/discovery.go +++ b/vendor/k8s.io/client-go/discovery/fake/discovery.go @@ -141,7 +141,10 @@ func (c *FakeDiscovery) ServerVersion() (*version.Info, error) { action := testing.ActionImpl{} action.Verb = "get" action.Resource = schema.GroupVersionResource{Resource: "version"} - c.Invokes(action, nil) + _, err := c.Invokes(action, nil) + if err != nil { + return nil, err + } if c.FakedServerVersion != nil { return c.FakedServerVersion, nil diff --git a/vendor/k8s.io/client-go/dynamic/dynamicinformer/informer.go b/vendor/k8s.io/client-go/dynamic/dynamicinformer/informer.go new file mode 100644 index 0000000000..62d01339db --- /dev/null +++ b/vendor/k8s.io/client-go/dynamic/dynamicinformer/informer.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 dynamicinformer + +import ( + "context" + "sync" + "time" + + 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" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/dynamic/dynamiclister" + "k8s.io/client-go/informers" + "k8s.io/client-go/tools/cache" +) + +// NewDynamicSharedInformerFactory constructs a new instance of dynamicSharedInformerFactory for all namespaces. +func NewDynamicSharedInformerFactory(client dynamic.Interface, defaultResync time.Duration) DynamicSharedInformerFactory { + return NewFilteredDynamicSharedInformerFactory(client, defaultResync, metav1.NamespaceAll, nil) +} + +// NewFilteredDynamicSharedInformerFactory constructs a new instance of dynamicSharedInformerFactory. +// Listers obtained via this factory will be subject to the same filters as specified here. +func NewFilteredDynamicSharedInformerFactory(client dynamic.Interface, defaultResync time.Duration, namespace string, tweakListOptions TweakListOptionsFunc) DynamicSharedInformerFactory { + return &dynamicSharedInformerFactory{ + client: client, + defaultResync: defaultResync, + namespace: namespace, + informers: map[schema.GroupVersionResource]informers.GenericInformer{}, + startedInformers: make(map[schema.GroupVersionResource]bool), + tweakListOptions: tweakListOptions, + } +} + +type dynamicSharedInformerFactory struct { + client dynamic.Interface + defaultResync time.Duration + namespace string + + lock sync.Mutex + informers map[schema.GroupVersionResource]informers.GenericInformer + // startedInformers is used for tracking which informers have been started. + // This allows Start() to be called multiple times safely. + startedInformers map[schema.GroupVersionResource]bool + tweakListOptions TweakListOptionsFunc + + // wg tracks how many goroutines were started. + wg sync.WaitGroup + // shuttingDown is true when Shutdown has been called. It may still be running + // because it needs to wait for goroutines. + shuttingDown bool +} + +var _ DynamicSharedInformerFactory = &dynamicSharedInformerFactory{} + +func (f *dynamicSharedInformerFactory) ForResource(gvr schema.GroupVersionResource) informers.GenericInformer { + f.lock.Lock() + defer f.lock.Unlock() + + key := gvr + informer, exists := f.informers[key] + if exists { + return informer + } + + informer = NewFilteredDynamicInformer(f.client, gvr, f.namespace, f.defaultResync, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + f.informers[key] = informer + + return informer +} + +// Start initializes all requested informers. +func (f *dynamicSharedInformerFactory) Start(stopCh <-chan struct{}) { + f.lock.Lock() + defer f.lock.Unlock() + + if f.shuttingDown { + return + } + + for informerType, informer := range f.informers { + if !f.startedInformers[informerType] { + f.wg.Add(1) + // We need a new variable in each loop iteration, + // otherwise the goroutine would use the loop variable + // and that keeps changing. + informer := informer.Informer() + go func() { + defer f.wg.Done() + informer.Run(stopCh) + }() + f.startedInformers[informerType] = true + } + } +} + +// WaitForCacheSync waits for all started informers' cache were synced. +func (f *dynamicSharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[schema.GroupVersionResource]bool { + informers := func() map[schema.GroupVersionResource]cache.SharedIndexInformer { + f.lock.Lock() + defer f.lock.Unlock() + + informers := map[schema.GroupVersionResource]cache.SharedIndexInformer{} + for informerType, informer := range f.informers { + if f.startedInformers[informerType] { + informers[informerType] = informer.Informer() + } + } + return informers + }() + + res := map[schema.GroupVersionResource]bool{} + for informType, informer := range informers { + res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) + } + return res +} + +func (f *dynamicSharedInformerFactory) Shutdown() { + // Will return immediately if there is nothing to wait for. + defer f.wg.Wait() + + f.lock.Lock() + defer f.lock.Unlock() + f.shuttingDown = true +} + +// NewFilteredDynamicInformer constructs a new informer for a dynamic type. +func NewFilteredDynamicInformer(client dynamic.Interface, gvr schema.GroupVersionResource, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions TweakListOptionsFunc) informers.GenericInformer { + return &dynamicInformer{ + gvr: gvr, + informer: cache.NewSharedIndexInformerWithOptions( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Resource(gvr).Namespace(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Resource(gvr).Namespace(namespace).Watch(context.TODO(), options) + }, + }, + &unstructured.Unstructured{}, + cache.SharedIndexInformerOptions{ + ResyncPeriod: resyncPeriod, + Indexers: indexers, + ObjectDescription: gvr.String(), + }, + ), + } +} + +type dynamicInformer struct { + informer cache.SharedIndexInformer + gvr schema.GroupVersionResource +} + +var _ informers.GenericInformer = &dynamicInformer{} + +func (d *dynamicInformer) Informer() cache.SharedIndexInformer { + return d.informer +} + +func (d *dynamicInformer) Lister() cache.GenericLister { + return dynamiclister.NewRuntimeObjectShim(dynamiclister.New(d.informer.GetIndexer(), d.gvr)) +} diff --git a/vendor/k8s.io/client-go/dynamic/dynamicinformer/interface.go b/vendor/k8s.io/client-go/dynamic/dynamicinformer/interface.go new file mode 100644 index 0000000000..0419ef4f86 --- /dev/null +++ b/vendor/k8s.io/client-go/dynamic/dynamicinformer/interface.go @@ -0,0 +1,53 @@ +/* +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 dynamicinformer + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/informers" +) + +// DynamicSharedInformerFactory provides access to a shared informer and lister for dynamic client +type DynamicSharedInformerFactory interface { + // Start initializes all requested informers. They are handled in goroutines + // which run until the stop channel gets closed. + Start(stopCh <-chan struct{}) + + // ForResource gives generic access to a shared informer of the matching type. + ForResource(gvr schema.GroupVersionResource) informers.GenericInformer + + // WaitForCacheSync blocks until all started informers' caches were synced + // or the stop channel gets closed. + WaitForCacheSync(stopCh <-chan struct{}) map[schema.GroupVersionResource]bool + + // Shutdown marks a factory as shutting down. At that point no new + // informers can be started anymore and Start will return without + // doing anything. + // + // In addition, Shutdown blocks until all goroutines have terminated. For that + // to happen, the close channel(s) that they were started with must be closed, + // either before Shutdown gets called or while it is waiting. + // + // Shutdown may be called multiple times, even concurrently. All such calls will + // block until all goroutines have terminated. + Shutdown() +} + +// TweakListOptionsFunc defines the signature of a helper function +// that wants to provide more listing options to API +type TweakListOptionsFunc func(*metav1.ListOptions) diff --git a/vendor/k8s.io/client-go/dynamic/dynamiclister/interface.go b/vendor/k8s.io/client-go/dynamic/dynamiclister/interface.go new file mode 100644 index 0000000000..c39cbee925 --- /dev/null +++ b/vendor/k8s.io/client-go/dynamic/dynamiclister/interface.go @@ -0,0 +1,40 @@ +/* +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 dynamiclister + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" +) + +// Lister helps list resources. +type Lister interface { + // List lists all resources in the indexer. + List(selector labels.Selector) (ret []*unstructured.Unstructured, err error) + // Get retrieves a resource from the indexer with the given name + Get(name string) (*unstructured.Unstructured, error) + // Namespace returns an object that can list and get resources in a given namespace. + Namespace(namespace string) NamespaceLister +} + +// NamespaceLister helps list and get resources. +type NamespaceLister interface { + // List lists all resources in the indexer for a given namespace. + List(selector labels.Selector) (ret []*unstructured.Unstructured, err error) + // Get retrieves a resource from the indexer for a given namespace and name. + Get(name string) (*unstructured.Unstructured, error) +} diff --git a/vendor/k8s.io/client-go/dynamic/dynamiclister/lister.go b/vendor/k8s.io/client-go/dynamic/dynamiclister/lister.go new file mode 100644 index 0000000000..a50fc471e9 --- /dev/null +++ b/vendor/k8s.io/client-go/dynamic/dynamiclister/lister.go @@ -0,0 +1,91 @@ +/* +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 dynamiclister + +import ( + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/tools/cache" +) + +var _ Lister = &dynamicLister{} +var _ NamespaceLister = &dynamicNamespaceLister{} + +// dynamicLister implements the Lister interface. +type dynamicLister struct { + indexer cache.Indexer + gvr schema.GroupVersionResource +} + +// New returns a new Lister. +func New(indexer cache.Indexer, gvr schema.GroupVersionResource) Lister { + return &dynamicLister{indexer: indexer, gvr: gvr} +} + +// List lists all resources in the indexer. +func (l *dynamicLister) List(selector labels.Selector) (ret []*unstructured.Unstructured, err error) { + err = cache.ListAll(l.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*unstructured.Unstructured)) + }) + return ret, err +} + +// Get retrieves a resource from the indexer with the given name +func (l *dynamicLister) Get(name string) (*unstructured.Unstructured, error) { + obj, exists, err := l.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(l.gvr.GroupResource(), name) + } + return obj.(*unstructured.Unstructured), nil +} + +// Namespace returns an object that can list and get resources from a given namespace. +func (l *dynamicLister) Namespace(namespace string) NamespaceLister { + return &dynamicNamespaceLister{indexer: l.indexer, namespace: namespace, gvr: l.gvr} +} + +// dynamicNamespaceLister implements the NamespaceLister interface. +type dynamicNamespaceLister struct { + indexer cache.Indexer + namespace string + gvr schema.GroupVersionResource +} + +// List lists all resources in the indexer for a given namespace. +func (l *dynamicNamespaceLister) List(selector labels.Selector) (ret []*unstructured.Unstructured, err error) { + err = cache.ListAllByNamespace(l.indexer, l.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*unstructured.Unstructured)) + }) + return ret, err +} + +// Get retrieves a resource from the indexer for a given namespace and name. +func (l *dynamicNamespaceLister) Get(name string) (*unstructured.Unstructured, error) { + obj, exists, err := l.indexer.GetByKey(l.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(l.gvr.GroupResource(), name) + } + return obj.(*unstructured.Unstructured), nil +} diff --git a/vendor/k8s.io/client-go/dynamic/dynamiclister/shim.go b/vendor/k8s.io/client-go/dynamic/dynamiclister/shim.go new file mode 100644 index 0000000000..92a5f54af9 --- /dev/null +++ b/vendor/k8s.io/client-go/dynamic/dynamiclister/shim.go @@ -0,0 +1,87 @@ +/* +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 dynamiclister + +import ( + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +var _ cache.GenericLister = &dynamicListerShim{} +var _ cache.GenericNamespaceLister = &dynamicNamespaceListerShim{} + +// dynamicListerShim implements the cache.GenericLister interface. +type dynamicListerShim struct { + lister Lister +} + +// NewRuntimeObjectShim returns a new shim for Lister. +// It wraps Lister so that it implements cache.GenericLister interface +func NewRuntimeObjectShim(lister Lister) cache.GenericLister { + return &dynamicListerShim{lister: lister} +} + +// List will return all objects across namespaces +func (s *dynamicListerShim) List(selector labels.Selector) (ret []runtime.Object, err error) { + objs, err := s.lister.List(selector) + if err != nil { + return nil, err + } + + ret = make([]runtime.Object, len(objs)) + for index, obj := range objs { + ret[index] = obj + } + return ret, err +} + +// Get will attempt to retrieve assuming that name==key +func (s *dynamicListerShim) Get(name string) (runtime.Object, error) { + return s.lister.Get(name) +} + +func (s *dynamicListerShim) ByNamespace(namespace string) cache.GenericNamespaceLister { + return &dynamicNamespaceListerShim{ + namespaceLister: s.lister.Namespace(namespace), + } +} + +// dynamicNamespaceListerShim implements the NamespaceLister interface. +// It wraps NamespaceLister so that it implements cache.GenericNamespaceLister interface +type dynamicNamespaceListerShim struct { + namespaceLister NamespaceLister +} + +// List will return all objects in this namespace +func (ns *dynamicNamespaceListerShim) List(selector labels.Selector) (ret []runtime.Object, err error) { + objs, err := ns.namespaceLister.List(selector) + if err != nil { + return nil, err + } + + ret = make([]runtime.Object, len(objs)) + for index, obj := range objs { + ret[index] = obj + } + return ret, err +} + +// Get will attempt to retrieve by namespace and name +func (ns *dynamicNamespaceListerShim) Get(name string) (runtime.Object, error) { + return ns.namespaceLister.Get(name) +} diff --git a/vendor/k8s.io/client-go/informers/certificates/interface.go b/vendor/k8s.io/client-go/informers/certificates/interface.go index e38d01177c..39a4e29111 100644 --- a/vendor/k8s.io/client-go/informers/certificates/interface.go +++ b/vendor/k8s.io/client-go/informers/certificates/interface.go @@ -20,6 +20,7 @@ package certificates import ( v1 "k8s.io/client-go/informers/certificates/v1" + v1alpha1 "k8s.io/client-go/informers/certificates/v1alpha1" v1beta1 "k8s.io/client-go/informers/certificates/v1beta1" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" ) @@ -28,6 +29,8 @@ import ( type Interface interface { // V1 provides access to shared informers for resources in V1. V1() v1.Interface + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface // V1beta1 provides access to shared informers for resources in V1beta1. V1beta1() v1beta1.Interface } @@ -48,6 +51,11 @@ func (g *group) V1() v1.Interface { return v1.New(g.factory, g.namespace, g.tweakListOptions) } +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} + // V1beta1 returns a new v1beta1.Interface. func (g *group) V1beta1() v1beta1.Interface { return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha1/podscheduling.go b/vendor/k8s.io/client-go/informers/certificates/v1alpha1/clustertrustbundle.go similarity index 52% rename from vendor/k8s.io/client-go/informers/resource/v1alpha1/podscheduling.go rename to vendor/k8s.io/client-go/informers/certificates/v1alpha1/clustertrustbundle.go index 87b4c34e15..e8b3415870 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1alpha1/podscheduling.go +++ b/vendor/k8s.io/client-go/informers/certificates/v1alpha1/clustertrustbundle.go @@ -22,69 +22,68 @@ import ( "context" time "time" - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" - v1alpha1 "k8s.io/client-go/listers/resource/v1alpha1" + v1alpha1 "k8s.io/client-go/listers/certificates/v1alpha1" cache "k8s.io/client-go/tools/cache" ) -// PodSchedulingInformer provides access to a shared informer and lister for -// PodSchedulings. -type PodSchedulingInformer interface { +// ClusterTrustBundleInformer provides access to a shared informer and lister for +// ClusterTrustBundles. +type ClusterTrustBundleInformer interface { Informer() cache.SharedIndexInformer - Lister() v1alpha1.PodSchedulingLister + Lister() v1alpha1.ClusterTrustBundleLister } -type podSchedulingInformer struct { +type clusterTrustBundleInformer struct { factory internalinterfaces.SharedInformerFactory tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string } -// NewPodSchedulingInformer constructs a new informer for PodScheduling type. +// NewClusterTrustBundleInformer constructs a new informer for ClusterTrustBundle 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 NewPodSchedulingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPodSchedulingInformer(client, namespace, resyncPeriod, indexers, nil) +func NewClusterTrustBundleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterTrustBundleInformer(client, resyncPeriod, indexers, nil) } -// NewFilteredPodSchedulingInformer constructs a new informer for PodScheduling type. +// NewFilteredClusterTrustBundleInformer constructs a new informer for ClusterTrustBundle 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 NewFilteredPodSchedulingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { +func NewFilteredClusterTrustBundleInformer(client kubernetes.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.ResourceV1alpha1().PodSchedulings(namespace).List(context.TODO(), options) + return client.CertificatesV1alpha1().ClusterTrustBundles().List(context.TODO(), options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha1().PodSchedulings(namespace).Watch(context.TODO(), options) + return client.CertificatesV1alpha1().ClusterTrustBundles().Watch(context.TODO(), options) }, }, - &resourcev1alpha1.PodScheduling{}, + &certificatesv1alpha1.ClusterTrustBundle{}, resyncPeriod, indexers, ) } -func (f *podSchedulingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPodSchedulingInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +func (f *clusterTrustBundleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterTrustBundleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) } -func (f *podSchedulingInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&resourcev1alpha1.PodScheduling{}, f.defaultInformer) +func (f *clusterTrustBundleInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&certificatesv1alpha1.ClusterTrustBundle{}, f.defaultInformer) } -func (f *podSchedulingInformer) Lister() v1alpha1.PodSchedulingLister { - return v1alpha1.NewPodSchedulingLister(f.Informer().GetIndexer()) +func (f *clusterTrustBundleInformer) Lister() v1alpha1.ClusterTrustBundleLister { + return v1alpha1.NewClusterTrustBundleLister(f.Informer().GetIndexer()) } diff --git a/vendor/k8s.io/client-go/informers/certificates/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/certificates/v1alpha1/interface.go new file mode 100644 index 0000000000..40ce8f42db --- /dev/null +++ b/vendor/k8s.io/client-go/informers/certificates/v1alpha1/interface.go @@ -0,0 +1,45 @@ +/* +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 v1alpha1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ClusterTrustBundles returns a ClusterTrustBundleInformer. + ClusterTrustBundles() ClusterTrustBundleInformer +} + +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} +} + +// ClusterTrustBundles returns a ClusterTrustBundleInformer. +func (v *version) ClusterTrustBundles() ClusterTrustBundleInformer { + return &clusterTrustBundleInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/doc.go b/vendor/k8s.io/client-go/informers/doc.go new file mode 100644 index 0000000000..231bffb69b --- /dev/null +++ b/vendor/k8s.io/client-go/informers/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2023 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 informers provides generated informers for Kubernetes APIs. +package informers diff --git a/vendor/k8s.io/client-go/informers/extensions/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/extensions/v1beta1/interface.go index 6f0bea7e87..600741e3a2 100644 --- a/vendor/k8s.io/client-go/informers/extensions/v1beta1/interface.go +++ b/vendor/k8s.io/client-go/informers/extensions/v1beta1/interface.go @@ -32,8 +32,6 @@ type Interface interface { Ingresses() IngressInformer // NetworkPolicies returns a NetworkPolicyInformer. NetworkPolicies() NetworkPolicyInformer - // PodSecurityPolicies returns a PodSecurityPolicyInformer. - PodSecurityPolicies() PodSecurityPolicyInformer // ReplicaSets returns a ReplicaSetInformer. ReplicaSets() ReplicaSetInformer } @@ -69,11 +67,6 @@ func (v *version) NetworkPolicies() NetworkPolicyInformer { return &networkPolicyInformer{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} -} - // ReplicaSets returns a ReplicaSetInformer. func (v *version) ReplicaSets() ReplicaSetInformer { return &replicaSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/vendor/k8s.io/client-go/informers/generic.go b/vendor/k8s.io/client-go/informers/generic.go index 59505bddaa..2b63a8028c 100644 --- a/vendor/k8s.io/client-go/informers/generic.go +++ b/vendor/k8s.io/client-go/informers/generic.go @@ -35,6 +35,7 @@ import ( batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" certificatesv1 "k8s.io/api/certificates/v1" + certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1" certificatesv1beta1 "k8s.io/api/certificates/v1beta1" coordinationv1 "k8s.io/api/coordination/v1" coordinationv1beta1 "k8s.io/api/coordination/v1beta1" @@ -59,7 +60,7 @@ import ( rbacv1 "k8s.io/api/rbac/v1" rbacv1alpha1 "k8s.io/api/rbac/v1alpha1" rbacv1beta1 "k8s.io/api/rbac/v1beta1" - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" schedulingv1 "k8s.io/api/scheduling/v1" schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" schedulingv1beta1 "k8s.io/api/scheduling/v1beta1" @@ -176,6 +177,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case certificatesv1.SchemeGroupVersion.WithResource("certificatesigningrequests"): return &genericInformer{resource: resource.GroupResource(), informer: f.Certificates().V1().CertificateSigningRequests().Informer()}, nil + // Group=certificates.k8s.io, Version=v1alpha1 + case certificatesv1alpha1.SchemeGroupVersion.WithResource("clustertrustbundles"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Certificates().V1alpha1().ClusterTrustBundles().Informer()}, nil + // Group=certificates.k8s.io, Version=v1beta1 case certificatesv1beta1.SchemeGroupVersion.WithResource("certificatesigningrequests"): return &genericInformer{resource: resource.GroupResource(), informer: f.Certificates().V1beta1().CertificateSigningRequests().Informer()}, nil @@ -247,8 +252,6 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().V1beta1().Ingresses().Informer()}, nil case extensionsv1beta1.SchemeGroupVersion.WithResource("networkpolicies"): return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().V1beta1().NetworkPolicies().Informer()}, nil - case extensionsv1beta1.SchemeGroupVersion.WithResource("podsecuritypolicies"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().V1beta1().PodSecurityPolicies().Informer()}, nil case extensionsv1beta1.SchemeGroupVersion.WithResource("replicasets"): return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().V1beta1().ReplicaSets().Informer()}, nil @@ -291,6 +294,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource // Group=networking.k8s.io, Version=v1alpha1 case networkingv1alpha1.SchemeGroupVersion.WithResource("clustercidrs"): return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1alpha1().ClusterCIDRs().Informer()}, nil + case networkingv1alpha1.SchemeGroupVersion.WithResource("ipaddresses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1alpha1().IPAddresses().Informer()}, nil // Group=networking.k8s.io, Version=v1beta1 case networkingv1beta1.SchemeGroupVersion.WithResource("ingresses"): @@ -350,15 +355,15 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case rbacv1beta1.SchemeGroupVersion.WithResource("rolebindings"): return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1beta1().RoleBindings().Informer()}, nil - // Group=resource.k8s.io, Version=v1alpha1 - case resourcev1alpha1.SchemeGroupVersion.WithResource("podschedulings"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha1().PodSchedulings().Informer()}, nil - case resourcev1alpha1.SchemeGroupVersion.WithResource("resourceclaims"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha1().ResourceClaims().Informer()}, nil - case resourcev1alpha1.SchemeGroupVersion.WithResource("resourceclaimtemplates"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha1().ResourceClaimTemplates().Informer()}, nil - case resourcev1alpha1.SchemeGroupVersion.WithResource("resourceclasses"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha1().ResourceClasses().Informer()}, nil + // Group=resource.k8s.io, Version=v1alpha2 + case v1alpha2.SchemeGroupVersion.WithResource("podschedulingcontexts"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().PodSchedulingContexts().Informer()}, nil + case v1alpha2.SchemeGroupVersion.WithResource("resourceclaims"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClaims().Informer()}, nil + case v1alpha2.SchemeGroupVersion.WithResource("resourceclaimtemplates"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClaimTemplates().Informer()}, nil + case v1alpha2.SchemeGroupVersion.WithResource("resourceclasses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClasses().Informer()}, nil // Group=scheduling.k8s.io, Version=v1 case schedulingv1.SchemeGroupVersion.WithResource("priorityclasses"): diff --git a/vendor/k8s.io/client-go/informers/networking/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/networking/v1alpha1/interface.go index c51b748801..07e7d208ca 100644 --- a/vendor/k8s.io/client-go/informers/networking/v1alpha1/interface.go +++ b/vendor/k8s.io/client-go/informers/networking/v1alpha1/interface.go @@ -26,6 +26,8 @@ import ( type Interface interface { // ClusterCIDRs returns a ClusterCIDRInformer. ClusterCIDRs() ClusterCIDRInformer + // IPAddresses returns a IPAddressInformer. + IPAddresses() IPAddressInformer } type version struct { @@ -43,3 +45,8 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList func (v *version) ClusterCIDRs() ClusterCIDRInformer { return &clusterCIDRInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} } + +// IPAddresses returns a IPAddressInformer. +func (v *version) IPAddresses() IPAddressInformer { + return &iPAddressInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/extensions/v1beta1/podsecuritypolicy.go b/vendor/k8s.io/client-go/informers/networking/v1alpha1/ipaddress.go similarity index 50% rename from vendor/k8s.io/client-go/informers/extensions/v1beta1/podsecuritypolicy.go rename to vendor/k8s.io/client-go/informers/networking/v1alpha1/ipaddress.go index 11be2751cc..a1083dbf0a 100644 --- a/vendor/k8s.io/client-go/informers/extensions/v1beta1/podsecuritypolicy.go +++ b/vendor/k8s.io/client-go/informers/networking/v1alpha1/ipaddress.go @@ -16,74 +16,74 @@ limitations under the License. // Code generated by informer-gen. DO NOT EDIT. -package v1beta1 +package v1alpha1 import ( "context" time "time" - extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + networkingv1alpha1 "k8s.io/api/networking/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" - v1beta1 "k8s.io/client-go/listers/extensions/v1beta1" + v1alpha1 "k8s.io/client-go/listers/networking/v1alpha1" cache "k8s.io/client-go/tools/cache" ) -// PodSecurityPolicyInformer provides access to a shared informer and lister for -// PodSecurityPolicies. -type PodSecurityPolicyInformer interface { +// IPAddressInformer provides access to a shared informer and lister for +// IPAddresses. +type IPAddressInformer interface { Informer() cache.SharedIndexInformer - Lister() v1beta1.PodSecurityPolicyLister + Lister() v1alpha1.IPAddressLister } -type podSecurityPolicyInformer struct { +type iPAddressInformer struct { factory internalinterfaces.SharedInformerFactory tweakListOptions internalinterfaces.TweakListOptionsFunc } -// NewPodSecurityPolicyInformer constructs a new informer for PodSecurityPolicy type. +// NewIPAddressInformer constructs a new informer for IPAddress 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 kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPodSecurityPolicyInformer(client, resyncPeriod, indexers, nil) +func NewIPAddressInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredIPAddressInformer(client, resyncPeriod, indexers, nil) } -// NewFilteredPodSecurityPolicyInformer constructs a new informer for PodSecurityPolicy type. +// NewFilteredIPAddressInformer constructs a new informer for IPAddress 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 kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { +func NewFilteredIPAddressInformer(client kubernetes.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.ExtensionsV1beta1().PodSecurityPolicies().List(context.TODO(), options) + return client.NetworkingV1alpha1().IPAddresses().List(context.TODO(), options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ExtensionsV1beta1().PodSecurityPolicies().Watch(context.TODO(), options) + return client.NetworkingV1alpha1().IPAddresses().Watch(context.TODO(), options) }, }, - &extensionsv1beta1.PodSecurityPolicy{}, + &networkingv1alpha1.IPAddress{}, resyncPeriod, indexers, ) } -func (f *podSecurityPolicyInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPodSecurityPolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +func (f *iPAddressInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredIPAddressInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) } -func (f *podSecurityPolicyInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&extensionsv1beta1.PodSecurityPolicy{}, f.defaultInformer) +func (f *iPAddressInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&networkingv1alpha1.IPAddress{}, f.defaultInformer) } -func (f *podSecurityPolicyInformer) Lister() v1beta1.PodSecurityPolicyLister { - return v1beta1.NewPodSecurityPolicyLister(f.Informer().GetIndexer()) +func (f *iPAddressInformer) Lister() v1alpha1.IPAddressLister { + return v1alpha1.NewIPAddressLister(f.Informer().GetIndexer()) } diff --git a/vendor/k8s.io/client-go/informers/resource/interface.go b/vendor/k8s.io/client-go/informers/resource/interface.go index 6cf95b0d47..3fcce8ae9d 100644 --- a/vendor/k8s.io/client-go/informers/resource/interface.go +++ b/vendor/k8s.io/client-go/informers/resource/interface.go @@ -20,13 +20,13 @@ package resource import ( internalinterfaces "k8s.io/client-go/informers/internalinterfaces" - v1alpha1 "k8s.io/client-go/informers/resource/v1alpha1" + v1alpha2 "k8s.io/client-go/informers/resource/v1alpha2" ) // Interface provides access to each of this group's versions. type Interface interface { - // V1alpha1 provides access to shared informers for resources in V1alpha1. - V1alpha1() v1alpha1.Interface + // V1alpha2 provides access to shared informers for resources in V1alpha2. + V1alpha2() v1alpha2.Interface } type group struct { @@ -40,7 +40,7 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } -// V1alpha1 returns a new v1alpha1.Interface. -func (g *group) V1alpha1() v1alpha1.Interface { - return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +// V1alpha2 returns a new v1alpha2.Interface. +func (g *group) V1alpha2() v1alpha2.Interface { + return v1alpha2.New(g.factory, g.namespace, g.tweakListOptions) } diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/resource/v1alpha2/interface.go similarity index 84% rename from vendor/k8s.io/client-go/informers/resource/v1alpha1/interface.go rename to vendor/k8s.io/client-go/informers/resource/v1alpha2/interface.go index 4449dfa652..23f817c62e 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1alpha1/interface.go +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha2/interface.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by informer-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( internalinterfaces "k8s.io/client-go/informers/internalinterfaces" @@ -24,8 +24,8 @@ import ( // Interface provides access to all the informers in this group version. type Interface interface { - // PodSchedulings returns a PodSchedulingInformer. - PodSchedulings() PodSchedulingInformer + // PodSchedulingContexts returns a PodSchedulingContextInformer. + PodSchedulingContexts() PodSchedulingContextInformer // ResourceClaims returns a ResourceClaimInformer. ResourceClaims() ResourceClaimInformer // ResourceClaimTemplates returns a ResourceClaimTemplateInformer. @@ -45,9 +45,9 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } -// PodSchedulings returns a PodSchedulingInformer. -func (v *version) PodSchedulings() PodSchedulingInformer { - return &podSchedulingInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +// PodSchedulingContexts returns a PodSchedulingContextInformer. +func (v *version) PodSchedulingContexts() PodSchedulingContextInformer { + return &podSchedulingContextInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } // ResourceClaims returns a ResourceClaimInformer. diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha2/podschedulingcontext.go b/vendor/k8s.io/client-go/informers/resource/v1alpha2/podschedulingcontext.go new file mode 100644 index 0000000000..b4aabb3761 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha2/podschedulingcontext.go @@ -0,0 +1,90 @@ +/* +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 v1alpha2 + +import ( + "context" + time "time" + + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha2 "k8s.io/client-go/listers/resource/v1alpha2" + cache "k8s.io/client-go/tools/cache" +) + +// PodSchedulingContextInformer provides access to a shared informer and lister for +// PodSchedulingContexts. +type PodSchedulingContextInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha2.PodSchedulingContextLister +} + +type podSchedulingContextInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewPodSchedulingContextInformer constructs a new informer for PodSchedulingContext 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 NewPodSchedulingContextInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPodSchedulingContextInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredPodSchedulingContextInformer constructs a new informer for PodSchedulingContext 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 NewFilteredPodSchedulingContextInformer(client kubernetes.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.ResourceV1alpha2().PodSchedulingContexts(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().PodSchedulingContexts(namespace).Watch(context.TODO(), options) + }, + }, + &resourcev1alpha2.PodSchedulingContext{}, + resyncPeriod, + indexers, + ) +} + +func (f *podSchedulingContextInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPodSchedulingContextInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *podSchedulingContextInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&resourcev1alpha2.PodSchedulingContext{}, f.defaultInformer) +} + +func (f *podSchedulingContextInformer) Lister() v1alpha2.PodSchedulingContextLister { + return v1alpha2.NewPodSchedulingContextLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclaim.go b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaim.go similarity index 85% rename from vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclaim.go rename to vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaim.go index 10150c0207..3af9368919 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclaim.go +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaim.go @@ -16,19 +16,19 @@ limitations under the License. // Code generated by informer-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( "context" time "time" - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" - v1alpha1 "k8s.io/client-go/listers/resource/v1alpha1" + v1alpha2 "k8s.io/client-go/listers/resource/v1alpha2" cache "k8s.io/client-go/tools/cache" ) @@ -36,7 +36,7 @@ import ( // ResourceClaims. type ResourceClaimInformer interface { Informer() cache.SharedIndexInformer - Lister() v1alpha1.ResourceClaimLister + Lister() v1alpha2.ResourceClaimLister } type resourceClaimInformer struct { @@ -62,16 +62,16 @@ func NewFilteredResourceClaimInformer(client kubernetes.Interface, namespace str if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha1().ResourceClaims(namespace).List(context.TODO(), options) + return client.ResourceV1alpha2().ResourceClaims(namespace).List(context.TODO(), options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha1().ResourceClaims(namespace).Watch(context.TODO(), options) + return client.ResourceV1alpha2().ResourceClaims(namespace).Watch(context.TODO(), options) }, }, - &resourcev1alpha1.ResourceClaim{}, + &resourcev1alpha2.ResourceClaim{}, resyncPeriod, indexers, ) @@ -82,9 +82,9 @@ func (f *resourceClaimInformer) defaultInformer(client kubernetes.Interface, res } func (f *resourceClaimInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&resourcev1alpha1.ResourceClaim{}, f.defaultInformer) + return f.factory.InformerFor(&resourcev1alpha2.ResourceClaim{}, f.defaultInformer) } -func (f *resourceClaimInformer) Lister() v1alpha1.ResourceClaimLister { - return v1alpha1.NewResourceClaimLister(f.Informer().GetIndexer()) +func (f *resourceClaimInformer) Lister() v1alpha2.ResourceClaimLister { + return v1alpha2.NewResourceClaimLister(f.Informer().GetIndexer()) } diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclaimtemplate.go b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaimtemplate.go similarity index 86% rename from vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclaimtemplate.go rename to vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaimtemplate.go index cdffa49db7..13f4ad835c 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclaimtemplate.go +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaimtemplate.go @@ -16,19 +16,19 @@ limitations under the License. // Code generated by informer-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( "context" time "time" - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" - v1alpha1 "k8s.io/client-go/listers/resource/v1alpha1" + v1alpha2 "k8s.io/client-go/listers/resource/v1alpha2" cache "k8s.io/client-go/tools/cache" ) @@ -36,7 +36,7 @@ import ( // ResourceClaimTemplates. type ResourceClaimTemplateInformer interface { Informer() cache.SharedIndexInformer - Lister() v1alpha1.ResourceClaimTemplateLister + Lister() v1alpha2.ResourceClaimTemplateLister } type resourceClaimTemplateInformer struct { @@ -62,16 +62,16 @@ func NewFilteredResourceClaimTemplateInformer(client kubernetes.Interface, names if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha1().ResourceClaimTemplates(namespace).List(context.TODO(), options) + return client.ResourceV1alpha2().ResourceClaimTemplates(namespace).List(context.TODO(), options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha1().ResourceClaimTemplates(namespace).Watch(context.TODO(), options) + return client.ResourceV1alpha2().ResourceClaimTemplates(namespace).Watch(context.TODO(), options) }, }, - &resourcev1alpha1.ResourceClaimTemplate{}, + &resourcev1alpha2.ResourceClaimTemplate{}, resyncPeriod, indexers, ) @@ -82,9 +82,9 @@ func (f *resourceClaimTemplateInformer) defaultInformer(client kubernetes.Interf } func (f *resourceClaimTemplateInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&resourcev1alpha1.ResourceClaimTemplate{}, f.defaultInformer) + return f.factory.InformerFor(&resourcev1alpha2.ResourceClaimTemplate{}, f.defaultInformer) } -func (f *resourceClaimTemplateInformer) Lister() v1alpha1.ResourceClaimTemplateLister { - return v1alpha1.NewResourceClaimTemplateLister(f.Informer().GetIndexer()) +func (f *resourceClaimTemplateInformer) Lister() v1alpha2.ResourceClaimTemplateLister { + return v1alpha2.NewResourceClaimTemplateLister(f.Informer().GetIndexer()) } diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclass.go b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclass.go similarity index 85% rename from vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclass.go rename to vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclass.go index e6faa5d02e..cb76d78fe4 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclass.go +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclass.go @@ -16,19 +16,19 @@ limitations under the License. // Code generated by informer-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( "context" time "time" - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" - v1alpha1 "k8s.io/client-go/listers/resource/v1alpha1" + v1alpha2 "k8s.io/client-go/listers/resource/v1alpha2" cache "k8s.io/client-go/tools/cache" ) @@ -36,7 +36,7 @@ import ( // ResourceClasses. type ResourceClassInformer interface { Informer() cache.SharedIndexInformer - Lister() v1alpha1.ResourceClassLister + Lister() v1alpha2.ResourceClassLister } type resourceClassInformer struct { @@ -61,16 +61,16 @@ func NewFilteredResourceClassInformer(client kubernetes.Interface, resyncPeriod if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha1().ResourceClasses().List(context.TODO(), options) + return client.ResourceV1alpha2().ResourceClasses().List(context.TODO(), options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha1().ResourceClasses().Watch(context.TODO(), options) + return client.ResourceV1alpha2().ResourceClasses().Watch(context.TODO(), options) }, }, - &resourcev1alpha1.ResourceClass{}, + &resourcev1alpha2.ResourceClass{}, resyncPeriod, indexers, ) @@ -81,9 +81,9 @@ func (f *resourceClassInformer) defaultInformer(client kubernetes.Interface, res } func (f *resourceClassInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&resourcev1alpha1.ResourceClass{}, f.defaultInformer) + return f.factory.InformerFor(&resourcev1alpha2.ResourceClass{}, f.defaultInformer) } -func (f *resourceClassInformer) Lister() v1alpha1.ResourceClassLister { - return v1alpha1.NewResourceClassLister(f.Informer().GetIndexer()) +func (f *resourceClassInformer) Lister() v1alpha2.ResourceClassLister { + return v1alpha2.NewResourceClassLister(f.Informer().GetIndexer()) } diff --git a/vendor/k8s.io/client-go/kubernetes/clientset.go b/vendor/k8s.io/client-go/kubernetes/clientset.go index 9eecbb2a80..6345f2fb62 100644 --- a/vendor/k8s.io/client-go/kubernetes/clientset.go +++ b/vendor/k8s.io/client-go/kubernetes/clientset.go @@ -42,6 +42,7 @@ import ( batchv1 "k8s.io/client-go/kubernetes/typed/batch/v1" batchv1beta1 "k8s.io/client-go/kubernetes/typed/batch/v1beta1" certificatesv1 "k8s.io/client-go/kubernetes/typed/certificates/v1" + certificatesv1alpha1 "k8s.io/client-go/kubernetes/typed/certificates/v1alpha1" certificatesv1beta1 "k8s.io/client-go/kubernetes/typed/certificates/v1beta1" coordinationv1 "k8s.io/client-go/kubernetes/typed/coordination/v1" coordinationv1beta1 "k8s.io/client-go/kubernetes/typed/coordination/v1beta1" @@ -66,7 +67,7 @@ import ( rbacv1 "k8s.io/client-go/kubernetes/typed/rbac/v1" rbacv1alpha1 "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1" rbacv1beta1 "k8s.io/client-go/kubernetes/typed/rbac/v1beta1" - resourcev1alpha1 "k8s.io/client-go/kubernetes/typed/resource/v1alpha1" + resourcev1alpha2 "k8s.io/client-go/kubernetes/typed/resource/v1alpha2" schedulingv1 "k8s.io/client-go/kubernetes/typed/scheduling/v1" schedulingv1alpha1 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1" schedulingv1beta1 "k8s.io/client-go/kubernetes/typed/scheduling/v1beta1" @@ -99,6 +100,7 @@ type Interface interface { BatchV1beta1() batchv1beta1.BatchV1beta1Interface CertificatesV1() certificatesv1.CertificatesV1Interface CertificatesV1beta1() certificatesv1beta1.CertificatesV1beta1Interface + CertificatesV1alpha1() certificatesv1alpha1.CertificatesV1alpha1Interface CoordinationV1beta1() coordinationv1beta1.CoordinationV1beta1Interface CoordinationV1() coordinationv1.CoordinationV1Interface CoreV1() corev1.CoreV1Interface @@ -122,7 +124,7 @@ type Interface interface { RbacV1() rbacv1.RbacV1Interface RbacV1beta1() rbacv1beta1.RbacV1beta1Interface RbacV1alpha1() rbacv1alpha1.RbacV1alpha1Interface - ResourceV1alpha1() resourcev1alpha1.ResourceV1alpha1Interface + ResourceV1alpha2() resourcev1alpha2.ResourceV1alpha2Interface SchedulingV1alpha1() schedulingv1alpha1.SchedulingV1alpha1Interface SchedulingV1beta1() schedulingv1beta1.SchedulingV1beta1Interface SchedulingV1() schedulingv1.SchedulingV1Interface @@ -154,6 +156,7 @@ type Clientset struct { batchV1beta1 *batchv1beta1.BatchV1beta1Client certificatesV1 *certificatesv1.CertificatesV1Client certificatesV1beta1 *certificatesv1beta1.CertificatesV1beta1Client + certificatesV1alpha1 *certificatesv1alpha1.CertificatesV1alpha1Client coordinationV1beta1 *coordinationv1beta1.CoordinationV1beta1Client coordinationV1 *coordinationv1.CoordinationV1Client coreV1 *corev1.CoreV1Client @@ -177,7 +180,7 @@ type Clientset struct { rbacV1 *rbacv1.RbacV1Client rbacV1beta1 *rbacv1beta1.RbacV1beta1Client rbacV1alpha1 *rbacv1alpha1.RbacV1alpha1Client - resourceV1alpha1 *resourcev1alpha1.ResourceV1alpha1Client + resourceV1alpha2 *resourcev1alpha2.ResourceV1alpha2Client schedulingV1alpha1 *schedulingv1alpha1.SchedulingV1alpha1Client schedulingV1beta1 *schedulingv1beta1.SchedulingV1beta1Client schedulingV1 *schedulingv1.SchedulingV1Client @@ -286,6 +289,11 @@ func (c *Clientset) CertificatesV1beta1() certificatesv1beta1.CertificatesV1beta return c.certificatesV1beta1 } +// CertificatesV1alpha1 retrieves the CertificatesV1alpha1Client +func (c *Clientset) CertificatesV1alpha1() certificatesv1alpha1.CertificatesV1alpha1Interface { + return c.certificatesV1alpha1 +} + // CoordinationV1beta1 retrieves the CoordinationV1beta1Client func (c *Clientset) CoordinationV1beta1() coordinationv1beta1.CoordinationV1beta1Interface { return c.coordinationV1beta1 @@ -401,9 +409,9 @@ func (c *Clientset) RbacV1alpha1() rbacv1alpha1.RbacV1alpha1Interface { return c.rbacV1alpha1 } -// ResourceV1alpha1 retrieves the ResourceV1alpha1Client -func (c *Clientset) ResourceV1alpha1() resourcev1alpha1.ResourceV1alpha1Interface { - return c.resourceV1alpha1 +// ResourceV1alpha2 retrieves the ResourceV1alpha2Client +func (c *Clientset) ResourceV1alpha2() resourcev1alpha2.ResourceV1alpha2Interface { + return c.resourceV1alpha2 } // SchedulingV1alpha1 retrieves the SchedulingV1alpha1Client @@ -560,6 +568,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.certificatesV1alpha1, err = certificatesv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.coordinationV1beta1, err = coordinationv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -652,7 +664,7 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } - cs.resourceV1alpha1, err = resourcev1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) + cs.resourceV1alpha2, err = resourcev1alpha2.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err } @@ -721,6 +733,7 @@ func New(c rest.Interface) *Clientset { cs.batchV1beta1 = batchv1beta1.New(c) cs.certificatesV1 = certificatesv1.New(c) cs.certificatesV1beta1 = certificatesv1beta1.New(c) + cs.certificatesV1alpha1 = certificatesv1alpha1.New(c) cs.coordinationV1beta1 = coordinationv1beta1.New(c) cs.coordinationV1 = coordinationv1.New(c) cs.coreV1 = corev1.New(c) @@ -744,7 +757,7 @@ func New(c rest.Interface) *Clientset { cs.rbacV1 = rbacv1.New(c) cs.rbacV1beta1 = rbacv1beta1.New(c) cs.rbacV1alpha1 = rbacv1alpha1.New(c) - cs.resourceV1alpha1 = resourcev1alpha1.New(c) + cs.resourceV1alpha2 = resourcev1alpha2.New(c) cs.schedulingV1alpha1 = schedulingv1alpha1.New(c) cs.schedulingV1beta1 = schedulingv1beta1.New(c) cs.schedulingV1 = schedulingv1.New(c) diff --git a/vendor/k8s.io/client-go/kubernetes/doc.go b/vendor/k8s.io/client-go/kubernetes/doc.go index b272334ad0..9cef4242f2 100644 --- a/vendor/k8s.io/client-go/kubernetes/doc.go +++ b/vendor/k8s.io/client-go/kubernetes/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +Copyright 2023 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,7 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - -// This package has the automatically generated clientset. +// Package kubernetes holds packages which implement a clientset for Kubernetes +// APIs. package kubernetes diff --git a/vendor/k8s.io/client-go/kubernetes/fake/clientset_generated.go b/vendor/k8s.io/client-go/kubernetes/fake/clientset_generated.go index f4d621941e..25de81caa8 100644 --- a/vendor/k8s.io/client-go/kubernetes/fake/clientset_generated.go +++ b/vendor/k8s.io/client-go/kubernetes/fake/clientset_generated.go @@ -62,6 +62,8 @@ import ( fakebatchv1beta1 "k8s.io/client-go/kubernetes/typed/batch/v1beta1/fake" certificatesv1 "k8s.io/client-go/kubernetes/typed/certificates/v1" fakecertificatesv1 "k8s.io/client-go/kubernetes/typed/certificates/v1/fake" + certificatesv1alpha1 "k8s.io/client-go/kubernetes/typed/certificates/v1alpha1" + fakecertificatesv1alpha1 "k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/fake" certificatesv1beta1 "k8s.io/client-go/kubernetes/typed/certificates/v1beta1" fakecertificatesv1beta1 "k8s.io/client-go/kubernetes/typed/certificates/v1beta1/fake" coordinationv1 "k8s.io/client-go/kubernetes/typed/coordination/v1" @@ -110,8 +112,8 @@ import ( fakerbacv1alpha1 "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake" rbacv1beta1 "k8s.io/client-go/kubernetes/typed/rbac/v1beta1" fakerbacv1beta1 "k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake" - resourcev1alpha1 "k8s.io/client-go/kubernetes/typed/resource/v1alpha1" - fakeresourcev1alpha1 "k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake" + resourcev1alpha2 "k8s.io/client-go/kubernetes/typed/resource/v1alpha2" + fakeresourcev1alpha2 "k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake" schedulingv1 "k8s.io/client-go/kubernetes/typed/scheduling/v1" fakeschedulingv1 "k8s.io/client-go/kubernetes/typed/scheduling/v1/fake" schedulingv1alpha1 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1" @@ -277,6 +279,11 @@ func (c *Clientset) CertificatesV1beta1() certificatesv1beta1.CertificatesV1beta return &fakecertificatesv1beta1.FakeCertificatesV1beta1{Fake: &c.Fake} } +// CertificatesV1alpha1 retrieves the CertificatesV1alpha1Client +func (c *Clientset) CertificatesV1alpha1() certificatesv1alpha1.CertificatesV1alpha1Interface { + return &fakecertificatesv1alpha1.FakeCertificatesV1alpha1{Fake: &c.Fake} +} + // CoordinationV1beta1 retrieves the CoordinationV1beta1Client func (c *Clientset) CoordinationV1beta1() coordinationv1beta1.CoordinationV1beta1Interface { return &fakecoordinationv1beta1.FakeCoordinationV1beta1{Fake: &c.Fake} @@ -392,9 +399,9 @@ func (c *Clientset) RbacV1alpha1() rbacv1alpha1.RbacV1alpha1Interface { return &fakerbacv1alpha1.FakeRbacV1alpha1{Fake: &c.Fake} } -// ResourceV1alpha1 retrieves the ResourceV1alpha1Client -func (c *Clientset) ResourceV1alpha1() resourcev1alpha1.ResourceV1alpha1Interface { - return &fakeresourcev1alpha1.FakeResourceV1alpha1{Fake: &c.Fake} +// ResourceV1alpha2 retrieves the ResourceV1alpha2Client +func (c *Clientset) ResourceV1alpha2() resourcev1alpha2.ResourceV1alpha2Interface { + return &fakeresourcev1alpha2.FakeResourceV1alpha2{Fake: &c.Fake} } // SchedulingV1alpha1 retrieves the SchedulingV1alpha1Client diff --git a/vendor/k8s.io/client-go/kubernetes/fake/register.go b/vendor/k8s.io/client-go/kubernetes/fake/register.go index 30f42e25da..0091841858 100644 --- a/vendor/k8s.io/client-go/kubernetes/fake/register.go +++ b/vendor/k8s.io/client-go/kubernetes/fake/register.go @@ -38,6 +38,7 @@ import ( batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" certificatesv1 "k8s.io/api/certificates/v1" + certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1" certificatesv1beta1 "k8s.io/api/certificates/v1beta1" coordinationv1 "k8s.io/api/coordination/v1" coordinationv1beta1 "k8s.io/api/coordination/v1beta1" @@ -62,7 +63,7 @@ import ( rbacv1 "k8s.io/api/rbac/v1" rbacv1alpha1 "k8s.io/api/rbac/v1alpha1" rbacv1beta1 "k8s.io/api/rbac/v1beta1" - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" schedulingv1 "k8s.io/api/scheduling/v1" schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" schedulingv1beta1 "k8s.io/api/scheduling/v1beta1" @@ -100,6 +101,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ batchv1beta1.AddToScheme, certificatesv1.AddToScheme, certificatesv1beta1.AddToScheme, + certificatesv1alpha1.AddToScheme, coordinationv1beta1.AddToScheme, coordinationv1.AddToScheme, corev1.AddToScheme, @@ -123,7 +125,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ rbacv1.AddToScheme, rbacv1beta1.AddToScheme, rbacv1alpha1.AddToScheme, - resourcev1alpha1.AddToScheme, + resourcev1alpha2.AddToScheme, schedulingv1alpha1.AddToScheme, schedulingv1beta1.AddToScheme, schedulingv1.AddToScheme, diff --git a/vendor/k8s.io/client-go/kubernetes/scheme/register.go b/vendor/k8s.io/client-go/kubernetes/scheme/register.go index e43780529b..64d3ce2a7b 100644 --- a/vendor/k8s.io/client-go/kubernetes/scheme/register.go +++ b/vendor/k8s.io/client-go/kubernetes/scheme/register.go @@ -38,6 +38,7 @@ import ( batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" certificatesv1 "k8s.io/api/certificates/v1" + certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1" certificatesv1beta1 "k8s.io/api/certificates/v1beta1" coordinationv1 "k8s.io/api/coordination/v1" coordinationv1beta1 "k8s.io/api/coordination/v1beta1" @@ -62,7 +63,7 @@ import ( rbacv1 "k8s.io/api/rbac/v1" rbacv1alpha1 "k8s.io/api/rbac/v1alpha1" rbacv1beta1 "k8s.io/api/rbac/v1beta1" - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" schedulingv1 "k8s.io/api/scheduling/v1" schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" schedulingv1beta1 "k8s.io/api/scheduling/v1beta1" @@ -100,6 +101,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ batchv1beta1.AddToScheme, certificatesv1.AddToScheme, certificatesv1beta1.AddToScheme, + certificatesv1alpha1.AddToScheme, coordinationv1beta1.AddToScheme, coordinationv1.AddToScheme, corev1.AddToScheme, @@ -123,7 +125,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ rbacv1.AddToScheme, rbacv1beta1.AddToScheme, rbacv1alpha1.AddToScheme, - resourcev1alpha1.AddToScheme, + resourcev1alpha2.AddToScheme, schedulingv1alpha1.AddToScheme, schedulingv1beta1.AddToScheme, schedulingv1.AddToScheme, diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_mutatingwebhookconfiguration.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_mutatingwebhookconfiguration.go index bbd4cf007f..b88598b715 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_mutatingwebhookconfiguration.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_mutatingwebhookconfiguration.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - admissionregistrationv1 "k8s.io/api/admissionregistration/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsadmissionregistrationv1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1" + admissionregistrationv1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakeMutatingWebhookConfigurations struct { Fake *FakeAdmissionregistrationV1 } -var mutatingwebhookconfigurationsResource = schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1", Resource: "mutatingwebhookconfigurations"} +var mutatingwebhookconfigurationsResource = v1.SchemeGroupVersion.WithResource("mutatingwebhookconfigurations") -var mutatingwebhookconfigurationsKind = schema.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingWebhookConfiguration"} +var mutatingwebhookconfigurationsKind = v1.SchemeGroupVersion.WithKind("MutatingWebhookConfiguration") // Get takes name of the mutatingWebhookConfiguration, and returns the corresponding mutatingWebhookConfiguration object, and an error if there is any. -func (c *FakeMutatingWebhookConfigurations) Get(ctx context.Context, name string, options v1.GetOptions) (result *admissionregistrationv1.MutatingWebhookConfiguration, err error) { +func (c *FakeMutatingWebhookConfigurations) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.MutatingWebhookConfiguration, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(mutatingwebhookconfigurationsResource, name), &admissionregistrationv1.MutatingWebhookConfiguration{}) + Invokes(testing.NewRootGetAction(mutatingwebhookconfigurationsResource, name), &v1.MutatingWebhookConfiguration{}) if obj == nil { return nil, err } - return obj.(*admissionregistrationv1.MutatingWebhookConfiguration), err + return obj.(*v1.MutatingWebhookConfiguration), err } // List takes label and field selectors, and returns the list of MutatingWebhookConfigurations that match those selectors. -func (c *FakeMutatingWebhookConfigurations) List(ctx context.Context, opts v1.ListOptions) (result *admissionregistrationv1.MutatingWebhookConfigurationList, err error) { +func (c *FakeMutatingWebhookConfigurations) List(ctx context.Context, opts metav1.ListOptions) (result *v1.MutatingWebhookConfigurationList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(mutatingwebhookconfigurationsResource, mutatingwebhookconfigurationsKind, opts), &admissionregistrationv1.MutatingWebhookConfigurationList{}) + Invokes(testing.NewRootListAction(mutatingwebhookconfigurationsResource, mutatingwebhookconfigurationsKind, opts), &v1.MutatingWebhookConfigurationList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakeMutatingWebhookConfigurations) List(ctx context.Context, opts v1.Li if label == nil { label = labels.Everything() } - list := &admissionregistrationv1.MutatingWebhookConfigurationList{ListMeta: obj.(*admissionregistrationv1.MutatingWebhookConfigurationList).ListMeta} - for _, item := range obj.(*admissionregistrationv1.MutatingWebhookConfigurationList).Items { + list := &v1.MutatingWebhookConfigurationList{ListMeta: obj.(*v1.MutatingWebhookConfigurationList).ListMeta} + for _, item := range obj.(*v1.MutatingWebhookConfigurationList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,58 +73,58 @@ func (c *FakeMutatingWebhookConfigurations) List(ctx context.Context, opts v1.Li } // Watch returns a watch.Interface that watches the requested mutatingWebhookConfigurations. -func (c *FakeMutatingWebhookConfigurations) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeMutatingWebhookConfigurations) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(mutatingwebhookconfigurationsResource, opts)) } // Create takes the representation of a mutatingWebhookConfiguration and creates it. Returns the server's representation of the mutatingWebhookConfiguration, and an error, if there is any. -func (c *FakeMutatingWebhookConfigurations) Create(ctx context.Context, mutatingWebhookConfiguration *admissionregistrationv1.MutatingWebhookConfiguration, opts v1.CreateOptions) (result *admissionregistrationv1.MutatingWebhookConfiguration, err error) { +func (c *FakeMutatingWebhookConfigurations) Create(ctx context.Context, mutatingWebhookConfiguration *v1.MutatingWebhookConfiguration, opts metav1.CreateOptions) (result *v1.MutatingWebhookConfiguration, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(mutatingwebhookconfigurationsResource, mutatingWebhookConfiguration), &admissionregistrationv1.MutatingWebhookConfiguration{}) + Invokes(testing.NewRootCreateAction(mutatingwebhookconfigurationsResource, mutatingWebhookConfiguration), &v1.MutatingWebhookConfiguration{}) if obj == nil { return nil, err } - return obj.(*admissionregistrationv1.MutatingWebhookConfiguration), err + return obj.(*v1.MutatingWebhookConfiguration), err } // Update takes the representation of a mutatingWebhookConfiguration and updates it. Returns the server's representation of the mutatingWebhookConfiguration, and an error, if there is any. -func (c *FakeMutatingWebhookConfigurations) Update(ctx context.Context, mutatingWebhookConfiguration *admissionregistrationv1.MutatingWebhookConfiguration, opts v1.UpdateOptions) (result *admissionregistrationv1.MutatingWebhookConfiguration, err error) { +func (c *FakeMutatingWebhookConfigurations) Update(ctx context.Context, mutatingWebhookConfiguration *v1.MutatingWebhookConfiguration, opts metav1.UpdateOptions) (result *v1.MutatingWebhookConfiguration, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(mutatingwebhookconfigurationsResource, mutatingWebhookConfiguration), &admissionregistrationv1.MutatingWebhookConfiguration{}) + Invokes(testing.NewRootUpdateAction(mutatingwebhookconfigurationsResource, mutatingWebhookConfiguration), &v1.MutatingWebhookConfiguration{}) if obj == nil { return nil, err } - return obj.(*admissionregistrationv1.MutatingWebhookConfiguration), err + return obj.(*v1.MutatingWebhookConfiguration), err } // Delete takes name of the mutatingWebhookConfiguration and deletes it. Returns an error if one occurs. -func (c *FakeMutatingWebhookConfigurations) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeMutatingWebhookConfigurations) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(mutatingwebhookconfigurationsResource, name, opts), &admissionregistrationv1.MutatingWebhookConfiguration{}) + Invokes(testing.NewRootDeleteActionWithOptions(mutatingwebhookconfigurationsResource, name, opts), &v1.MutatingWebhookConfiguration{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeMutatingWebhookConfigurations) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeMutatingWebhookConfigurations) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(mutatingwebhookconfigurationsResource, listOpts) - _, err := c.Fake.Invokes(action, &admissionregistrationv1.MutatingWebhookConfigurationList{}) + _, err := c.Fake.Invokes(action, &v1.MutatingWebhookConfigurationList{}) return err } // Patch applies the patch and returns the patched mutatingWebhookConfiguration. -func (c *FakeMutatingWebhookConfigurations) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *admissionregistrationv1.MutatingWebhookConfiguration, err error) { +func (c *FakeMutatingWebhookConfigurations) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.MutatingWebhookConfiguration, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(mutatingwebhookconfigurationsResource, name, pt, data, subresources...), &admissionregistrationv1.MutatingWebhookConfiguration{}) + Invokes(testing.NewRootPatchSubresourceAction(mutatingwebhookconfigurationsResource, name, pt, data, subresources...), &v1.MutatingWebhookConfiguration{}) if obj == nil { return nil, err } - return obj.(*admissionregistrationv1.MutatingWebhookConfiguration), err + return obj.(*v1.MutatingWebhookConfiguration), err } // Apply takes the given apply declarative configuration, applies it and returns the applied mutatingWebhookConfiguration. -func (c *FakeMutatingWebhookConfigurations) Apply(ctx context.Context, mutatingWebhookConfiguration *applyconfigurationsadmissionregistrationv1.MutatingWebhookConfigurationApplyConfiguration, opts v1.ApplyOptions) (result *admissionregistrationv1.MutatingWebhookConfiguration, err error) { +func (c *FakeMutatingWebhookConfigurations) Apply(ctx context.Context, mutatingWebhookConfiguration *admissionregistrationv1.MutatingWebhookConfigurationApplyConfiguration, opts metav1.ApplyOptions) (result *v1.MutatingWebhookConfiguration, err error) { if mutatingWebhookConfiguration == nil { return nil, fmt.Errorf("mutatingWebhookConfiguration provided to Apply must not be nil") } @@ -138,9 +137,9 @@ func (c *FakeMutatingWebhookConfigurations) Apply(ctx context.Context, mutatingW return nil, fmt.Errorf("mutatingWebhookConfiguration.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(mutatingwebhookconfigurationsResource, *name, types.ApplyPatchType, data), &admissionregistrationv1.MutatingWebhookConfiguration{}) + Invokes(testing.NewRootPatchSubresourceAction(mutatingwebhookconfigurationsResource, *name, types.ApplyPatchType, data), &v1.MutatingWebhookConfiguration{}) if obj == nil { return nil, err } - return obj.(*admissionregistrationv1.MutatingWebhookConfiguration), err + return obj.(*v1.MutatingWebhookConfiguration), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_validatingwebhookconfiguration.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_validatingwebhookconfiguration.go index ee769dd3cb..a6951c736e 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_validatingwebhookconfiguration.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1/fake/fake_validatingwebhookconfiguration.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - admissionregistrationv1 "k8s.io/api/admissionregistration/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/admissionregistration/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsadmissionregistrationv1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1" + admissionregistrationv1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakeValidatingWebhookConfigurations struct { Fake *FakeAdmissionregistrationV1 } -var validatingwebhookconfigurationsResource = schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1", Resource: "validatingwebhookconfigurations"} +var validatingwebhookconfigurationsResource = v1.SchemeGroupVersion.WithResource("validatingwebhookconfigurations") -var validatingwebhookconfigurationsKind = schema.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "ValidatingWebhookConfiguration"} +var validatingwebhookconfigurationsKind = v1.SchemeGroupVersion.WithKind("ValidatingWebhookConfiguration") // Get takes name of the validatingWebhookConfiguration, and returns the corresponding validatingWebhookConfiguration object, and an error if there is any. -func (c *FakeValidatingWebhookConfigurations) Get(ctx context.Context, name string, options v1.GetOptions) (result *admissionregistrationv1.ValidatingWebhookConfiguration, err error) { +func (c *FakeValidatingWebhookConfigurations) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ValidatingWebhookConfiguration, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(validatingwebhookconfigurationsResource, name), &admissionregistrationv1.ValidatingWebhookConfiguration{}) + Invokes(testing.NewRootGetAction(validatingwebhookconfigurationsResource, name), &v1.ValidatingWebhookConfiguration{}) if obj == nil { return nil, err } - return obj.(*admissionregistrationv1.ValidatingWebhookConfiguration), err + return obj.(*v1.ValidatingWebhookConfiguration), err } // List takes label and field selectors, and returns the list of ValidatingWebhookConfigurations that match those selectors. -func (c *FakeValidatingWebhookConfigurations) List(ctx context.Context, opts v1.ListOptions) (result *admissionregistrationv1.ValidatingWebhookConfigurationList, err error) { +func (c *FakeValidatingWebhookConfigurations) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ValidatingWebhookConfigurationList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(validatingwebhookconfigurationsResource, validatingwebhookconfigurationsKind, opts), &admissionregistrationv1.ValidatingWebhookConfigurationList{}) + Invokes(testing.NewRootListAction(validatingwebhookconfigurationsResource, validatingwebhookconfigurationsKind, opts), &v1.ValidatingWebhookConfigurationList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakeValidatingWebhookConfigurations) List(ctx context.Context, opts v1. if label == nil { label = labels.Everything() } - list := &admissionregistrationv1.ValidatingWebhookConfigurationList{ListMeta: obj.(*admissionregistrationv1.ValidatingWebhookConfigurationList).ListMeta} - for _, item := range obj.(*admissionregistrationv1.ValidatingWebhookConfigurationList).Items { + list := &v1.ValidatingWebhookConfigurationList{ListMeta: obj.(*v1.ValidatingWebhookConfigurationList).ListMeta} + for _, item := range obj.(*v1.ValidatingWebhookConfigurationList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,58 +73,58 @@ func (c *FakeValidatingWebhookConfigurations) List(ctx context.Context, opts v1. } // Watch returns a watch.Interface that watches the requested validatingWebhookConfigurations. -func (c *FakeValidatingWebhookConfigurations) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeValidatingWebhookConfigurations) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(validatingwebhookconfigurationsResource, opts)) } // Create takes the representation of a validatingWebhookConfiguration and creates it. Returns the server's representation of the validatingWebhookConfiguration, and an error, if there is any. -func (c *FakeValidatingWebhookConfigurations) Create(ctx context.Context, validatingWebhookConfiguration *admissionregistrationv1.ValidatingWebhookConfiguration, opts v1.CreateOptions) (result *admissionregistrationv1.ValidatingWebhookConfiguration, err error) { +func (c *FakeValidatingWebhookConfigurations) Create(ctx context.Context, validatingWebhookConfiguration *v1.ValidatingWebhookConfiguration, opts metav1.CreateOptions) (result *v1.ValidatingWebhookConfiguration, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(validatingwebhookconfigurationsResource, validatingWebhookConfiguration), &admissionregistrationv1.ValidatingWebhookConfiguration{}) + Invokes(testing.NewRootCreateAction(validatingwebhookconfigurationsResource, validatingWebhookConfiguration), &v1.ValidatingWebhookConfiguration{}) if obj == nil { return nil, err } - return obj.(*admissionregistrationv1.ValidatingWebhookConfiguration), err + return obj.(*v1.ValidatingWebhookConfiguration), err } // Update takes the representation of a validatingWebhookConfiguration and updates it. Returns the server's representation of the validatingWebhookConfiguration, and an error, if there is any. -func (c *FakeValidatingWebhookConfigurations) Update(ctx context.Context, validatingWebhookConfiguration *admissionregistrationv1.ValidatingWebhookConfiguration, opts v1.UpdateOptions) (result *admissionregistrationv1.ValidatingWebhookConfiguration, err error) { +func (c *FakeValidatingWebhookConfigurations) Update(ctx context.Context, validatingWebhookConfiguration *v1.ValidatingWebhookConfiguration, opts metav1.UpdateOptions) (result *v1.ValidatingWebhookConfiguration, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(validatingwebhookconfigurationsResource, validatingWebhookConfiguration), &admissionregistrationv1.ValidatingWebhookConfiguration{}) + Invokes(testing.NewRootUpdateAction(validatingwebhookconfigurationsResource, validatingWebhookConfiguration), &v1.ValidatingWebhookConfiguration{}) if obj == nil { return nil, err } - return obj.(*admissionregistrationv1.ValidatingWebhookConfiguration), err + return obj.(*v1.ValidatingWebhookConfiguration), err } // Delete takes name of the validatingWebhookConfiguration and deletes it. Returns an error if one occurs. -func (c *FakeValidatingWebhookConfigurations) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeValidatingWebhookConfigurations) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(validatingwebhookconfigurationsResource, name, opts), &admissionregistrationv1.ValidatingWebhookConfiguration{}) + Invokes(testing.NewRootDeleteActionWithOptions(validatingwebhookconfigurationsResource, name, opts), &v1.ValidatingWebhookConfiguration{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeValidatingWebhookConfigurations) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeValidatingWebhookConfigurations) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(validatingwebhookconfigurationsResource, listOpts) - _, err := c.Fake.Invokes(action, &admissionregistrationv1.ValidatingWebhookConfigurationList{}) + _, err := c.Fake.Invokes(action, &v1.ValidatingWebhookConfigurationList{}) return err } // Patch applies the patch and returns the patched validatingWebhookConfiguration. -func (c *FakeValidatingWebhookConfigurations) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *admissionregistrationv1.ValidatingWebhookConfiguration, err error) { +func (c *FakeValidatingWebhookConfigurations) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ValidatingWebhookConfiguration, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(validatingwebhookconfigurationsResource, name, pt, data, subresources...), &admissionregistrationv1.ValidatingWebhookConfiguration{}) + Invokes(testing.NewRootPatchSubresourceAction(validatingwebhookconfigurationsResource, name, pt, data, subresources...), &v1.ValidatingWebhookConfiguration{}) if obj == nil { return nil, err } - return obj.(*admissionregistrationv1.ValidatingWebhookConfiguration), err + return obj.(*v1.ValidatingWebhookConfiguration), err } // Apply takes the given apply declarative configuration, applies it and returns the applied validatingWebhookConfiguration. -func (c *FakeValidatingWebhookConfigurations) Apply(ctx context.Context, validatingWebhookConfiguration *applyconfigurationsadmissionregistrationv1.ValidatingWebhookConfigurationApplyConfiguration, opts v1.ApplyOptions) (result *admissionregistrationv1.ValidatingWebhookConfiguration, err error) { +func (c *FakeValidatingWebhookConfigurations) Apply(ctx context.Context, validatingWebhookConfiguration *admissionregistrationv1.ValidatingWebhookConfigurationApplyConfiguration, opts metav1.ApplyOptions) (result *v1.ValidatingWebhookConfiguration, err error) { if validatingWebhookConfiguration == nil { return nil, fmt.Errorf("validatingWebhookConfiguration provided to Apply must not be nil") } @@ -138,9 +137,9 @@ func (c *FakeValidatingWebhookConfigurations) Apply(ctx context.Context, validat return nil, fmt.Errorf("validatingWebhookConfiguration.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(validatingwebhookconfigurationsResource, *name, types.ApplyPatchType, data), &admissionregistrationv1.ValidatingWebhookConfiguration{}) + Invokes(testing.NewRootPatchSubresourceAction(validatingwebhookconfigurationsResource, *name, types.ApplyPatchType, data), &v1.ValidatingWebhookConfiguration{}) if obj == nil { return nil, err } - return obj.(*admissionregistrationv1.ValidatingWebhookConfiguration), err + return obj.(*v1.ValidatingWebhookConfiguration), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/fake/fake_validatingadmissionpolicy.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/fake/fake_validatingadmissionpolicy.go index 2fed66b44d..f4358ce46c 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/fake/fake_validatingadmissionpolicy.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/fake/fake_validatingadmissionpolicy.go @@ -26,7 +26,6 @@ import ( v1alpha1 "k8s.io/api/admissionregistration/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" admissionregistrationv1alpha1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1" @@ -38,9 +37,9 @@ type FakeValidatingAdmissionPolicies struct { Fake *FakeAdmissionregistrationV1alpha1 } -var validatingadmissionpoliciesResource = schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Resource: "validatingadmissionpolicies"} +var validatingadmissionpoliciesResource = v1alpha1.SchemeGroupVersion.WithResource("validatingadmissionpolicies") -var validatingadmissionpoliciesKind = schema.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Kind: "ValidatingAdmissionPolicy"} +var validatingadmissionpoliciesKind = v1alpha1.SchemeGroupVersion.WithKind("ValidatingAdmissionPolicy") // Get takes name of the validatingAdmissionPolicy, and returns the corresponding validatingAdmissionPolicy object, and an error if there is any. func (c *FakeValidatingAdmissionPolicies) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) { @@ -99,6 +98,17 @@ func (c *FakeValidatingAdmissionPolicies) Update(ctx context.Context, validating return obj.(*v1alpha1.ValidatingAdmissionPolicy), 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 *FakeValidatingAdmissionPolicies) UpdateStatus(ctx context.Context, validatingAdmissionPolicy *v1alpha1.ValidatingAdmissionPolicy, opts v1.UpdateOptions) (*v1alpha1.ValidatingAdmissionPolicy, error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateSubresourceAction(validatingadmissionpoliciesResource, "status", validatingAdmissionPolicy), &v1alpha1.ValidatingAdmissionPolicy{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ValidatingAdmissionPolicy), err +} + // Delete takes name of the validatingAdmissionPolicy and deletes it. Returns an error if one occurs. func (c *FakeValidatingAdmissionPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. @@ -144,3 +154,25 @@ func (c *FakeValidatingAdmissionPolicies) Apply(ctx context.Context, validatingA } return obj.(*v1alpha1.ValidatingAdmissionPolicy), err } + +// ApplyStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). +func (c *FakeValidatingAdmissionPolicies) ApplyStatus(ctx context.Context, validatingAdmissionPolicy *admissionregistrationv1alpha1.ValidatingAdmissionPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) { + if validatingAdmissionPolicy == nil { + return nil, fmt.Errorf("validatingAdmissionPolicy provided to Apply must not be nil") + } + data, err := json.Marshal(validatingAdmissionPolicy) + if err != nil { + return nil, err + } + name := validatingAdmissionPolicy.Name + if name == nil { + return nil, fmt.Errorf("validatingAdmissionPolicy.Name must be provided to Apply") + } + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(validatingadmissionpoliciesResource, *name, types.ApplyPatchType, data, "status"), &v1alpha1.ValidatingAdmissionPolicy{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ValidatingAdmissionPolicy), err +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/fake/fake_validatingadmissionpolicybinding.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/fake/fake_validatingadmissionpolicybinding.go index 7c9cb88aab..c520655f9d 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/fake/fake_validatingadmissionpolicybinding.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/fake/fake_validatingadmissionpolicybinding.go @@ -26,7 +26,6 @@ import ( v1alpha1 "k8s.io/api/admissionregistration/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" admissionregistrationv1alpha1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1" @@ -38,9 +37,9 @@ type FakeValidatingAdmissionPolicyBindings struct { Fake *FakeAdmissionregistrationV1alpha1 } -var validatingadmissionpolicybindingsResource = schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Resource: "validatingadmissionpolicybindings"} +var validatingadmissionpolicybindingsResource = v1alpha1.SchemeGroupVersion.WithResource("validatingadmissionpolicybindings") -var validatingadmissionpolicybindingsKind = schema.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Kind: "ValidatingAdmissionPolicyBinding"} +var validatingadmissionpolicybindingsKind = v1alpha1.SchemeGroupVersion.WithKind("ValidatingAdmissionPolicyBinding") // Get takes name of the validatingAdmissionPolicyBinding, and returns the corresponding validatingAdmissionPolicyBinding object, and an error if there is any. func (c *FakeValidatingAdmissionPolicyBindings) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ValidatingAdmissionPolicyBinding, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/validatingadmissionpolicy.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/validatingadmissionpolicy.go index ba827f3c99..1d994b5abf 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/validatingadmissionpolicy.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/validatingadmissionpolicy.go @@ -43,6 +43,7 @@ type ValidatingAdmissionPoliciesGetter interface { type ValidatingAdmissionPolicyInterface interface { Create(ctx context.Context, validatingAdmissionPolicy *v1alpha1.ValidatingAdmissionPolicy, opts v1.CreateOptions) (*v1alpha1.ValidatingAdmissionPolicy, error) Update(ctx context.Context, validatingAdmissionPolicy *v1alpha1.ValidatingAdmissionPolicy, opts v1.UpdateOptions) (*v1alpha1.ValidatingAdmissionPolicy, error) + UpdateStatus(ctx context.Context, validatingAdmissionPolicy *v1alpha1.ValidatingAdmissionPolicy, opts v1.UpdateOptions) (*v1alpha1.ValidatingAdmissionPolicy, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ValidatingAdmissionPolicy, error) @@ -50,6 +51,7 @@ type ValidatingAdmissionPolicyInterface interface { Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ValidatingAdmissionPolicy, err error) Apply(ctx context.Context, validatingAdmissionPolicy *admissionregistrationv1alpha1.ValidatingAdmissionPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) + ApplyStatus(ctx context.Context, validatingAdmissionPolicy *admissionregistrationv1alpha1.ValidatingAdmissionPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) ValidatingAdmissionPolicyExpansion } @@ -132,6 +134,21 @@ func (c *validatingAdmissionPolicies) Update(ctx context.Context, validatingAdmi return } +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *validatingAdmissionPolicies) UpdateStatus(ctx context.Context, validatingAdmissionPolicy *v1alpha1.ValidatingAdmissionPolicy, opts v1.UpdateOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) { + result = &v1alpha1.ValidatingAdmissionPolicy{} + err = c.client.Put(). + Resource("validatingadmissionpolicies"). + Name(validatingAdmissionPolicy.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(validatingAdmissionPolicy). + Do(ctx). + Into(result) + return +} + // Delete takes name of the validatingAdmissionPolicy and deletes it. Returns an error if one occurs. func (c *validatingAdmissionPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { return c.client.Delete(). @@ -195,3 +212,32 @@ func (c *validatingAdmissionPolicies) Apply(ctx context.Context, validatingAdmis Into(result) return } + +// ApplyStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). +func (c *validatingAdmissionPolicies) ApplyStatus(ctx context.Context, validatingAdmissionPolicy *admissionregistrationv1alpha1.ValidatingAdmissionPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) { + if validatingAdmissionPolicy == nil { + return nil, fmt.Errorf("validatingAdmissionPolicy provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(validatingAdmissionPolicy) + if err != nil { + return nil, err + } + + name := validatingAdmissionPolicy.Name + if name == nil { + return nil, fmt.Errorf("validatingAdmissionPolicy.Name must be provided to Apply") + } + + result = &v1alpha1.ValidatingAdmissionPolicy{} + err = c.client.Patch(types.ApplyPatchType). + Resource("validatingadmissionpolicies"). + Name(*name). + SubResource("status"). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1/fake/fake_mutatingwebhookconfiguration.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1/fake/fake_mutatingwebhookconfiguration.go index a06bb7db10..9d85aff37f 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1/fake/fake_mutatingwebhookconfiguration.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1/fake/fake_mutatingwebhookconfiguration.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/admissionregistration/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" admissionregistrationv1beta1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1" @@ -38,9 +37,9 @@ type FakeMutatingWebhookConfigurations struct { Fake *FakeAdmissionregistrationV1beta1 } -var mutatingwebhookconfigurationsResource = schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1beta1", Resource: "mutatingwebhookconfigurations"} +var mutatingwebhookconfigurationsResource = v1beta1.SchemeGroupVersion.WithResource("mutatingwebhookconfigurations") -var mutatingwebhookconfigurationsKind = schema.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1beta1", Kind: "MutatingWebhookConfiguration"} +var mutatingwebhookconfigurationsKind = v1beta1.SchemeGroupVersion.WithKind("MutatingWebhookConfiguration") // Get takes name of the mutatingWebhookConfiguration, and returns the corresponding mutatingWebhookConfiguration object, and an error if there is any. func (c *FakeMutatingWebhookConfigurations) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.MutatingWebhookConfiguration, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1/fake/fake_validatingwebhookconfiguration.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1/fake/fake_validatingwebhookconfiguration.go index 27495b31de..41e3a7c1ee 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1/fake/fake_validatingwebhookconfiguration.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1/fake/fake_validatingwebhookconfiguration.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/admissionregistration/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" admissionregistrationv1beta1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1" @@ -38,9 +37,9 @@ type FakeValidatingWebhookConfigurations struct { Fake *FakeAdmissionregistrationV1beta1 } -var validatingwebhookconfigurationsResource = schema.GroupVersionResource{Group: "admissionregistration.k8s.io", Version: "v1beta1", Resource: "validatingwebhookconfigurations"} +var validatingwebhookconfigurationsResource = v1beta1.SchemeGroupVersion.WithResource("validatingwebhookconfigurations") -var validatingwebhookconfigurationsKind = schema.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1beta1", Kind: "ValidatingWebhookConfiguration"} +var validatingwebhookconfigurationsKind = v1beta1.SchemeGroupVersion.WithKind("ValidatingWebhookConfiguration") // Get takes name of the validatingWebhookConfiguration, and returns the corresponding validatingWebhookConfiguration object, and an error if there is any. func (c *FakeValidatingWebhookConfigurations) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ValidatingWebhookConfiguration, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/apiserverinternal/v1alpha1/fake/fake_storageversion.go b/vendor/k8s.io/client-go/kubernetes/typed/apiserverinternal/v1alpha1/fake/fake_storageversion.go index 8b6a84d7a9..738c68038b 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/apiserverinternal/v1alpha1/fake/fake_storageversion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/apiserverinternal/v1alpha1/fake/fake_storageversion.go @@ -26,7 +26,6 @@ import ( v1alpha1 "k8s.io/api/apiserverinternal/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" apiserverinternalv1alpha1 "k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1" @@ -38,9 +37,9 @@ type FakeStorageVersions struct { Fake *FakeInternalV1alpha1 } -var storageversionsResource = schema.GroupVersionResource{Group: "internal.apiserver.k8s.io", Version: "v1alpha1", Resource: "storageversions"} +var storageversionsResource = v1alpha1.SchemeGroupVersion.WithResource("storageversions") -var storageversionsKind = schema.GroupVersionKind{Group: "internal.apiserver.k8s.io", Version: "v1alpha1", Kind: "StorageVersion"} +var storageversionsKind = v1alpha1.SchemeGroupVersion.WithKind("StorageVersion") // Get takes name of the storageVersion, and returns the corresponding storageVersion object, and an error if there is any. func (c *FakeStorageVersions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.StorageVersion, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_controllerrevision.go b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_controllerrevision.go index 1116d6dffc..f691ba9acd 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_controllerrevision.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_controllerrevision.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - appsv1 "k8s.io/api/apps/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsappsv1 "k8s.io/client-go/applyconfigurations/apps/v1" + appsv1 "k8s.io/client-go/applyconfigurations/apps/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeControllerRevisions struct { ns string } -var controllerrevisionsResource = schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "controllerrevisions"} +var controllerrevisionsResource = v1.SchemeGroupVersion.WithResource("controllerrevisions") -var controllerrevisionsKind = schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "ControllerRevision"} +var controllerrevisionsKind = v1.SchemeGroupVersion.WithKind("ControllerRevision") // Get takes name of the controllerRevision, and returns the corresponding controllerRevision object, and an error if there is any. -func (c *FakeControllerRevisions) Get(ctx context.Context, name string, options v1.GetOptions) (result *appsv1.ControllerRevision, err error) { +func (c *FakeControllerRevisions) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ControllerRevision, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(controllerrevisionsResource, c.ns, name), &appsv1.ControllerRevision{}) + Invokes(testing.NewGetAction(controllerrevisionsResource, c.ns, name), &v1.ControllerRevision{}) if obj == nil { return nil, err } - return obj.(*appsv1.ControllerRevision), err + return obj.(*v1.ControllerRevision), err } // List takes label and field selectors, and returns the list of ControllerRevisions that match those selectors. -func (c *FakeControllerRevisions) List(ctx context.Context, opts v1.ListOptions) (result *appsv1.ControllerRevisionList, err error) { +func (c *FakeControllerRevisions) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ControllerRevisionList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(controllerrevisionsResource, controllerrevisionsKind, c.ns, opts), &appsv1.ControllerRevisionList{}) + Invokes(testing.NewListAction(controllerrevisionsResource, controllerrevisionsKind, c.ns, opts), &v1.ControllerRevisionList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeControllerRevisions) List(ctx context.Context, opts v1.ListOptions) if label == nil { label = labels.Everything() } - list := &appsv1.ControllerRevisionList{ListMeta: obj.(*appsv1.ControllerRevisionList).ListMeta} - for _, item := range obj.(*appsv1.ControllerRevisionList).Items { + list := &v1.ControllerRevisionList{ListMeta: obj.(*v1.ControllerRevisionList).ListMeta} + for _, item := range obj.(*v1.ControllerRevisionList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,63 +76,63 @@ func (c *FakeControllerRevisions) List(ctx context.Context, opts v1.ListOptions) } // Watch returns a watch.Interface that watches the requested controllerRevisions. -func (c *FakeControllerRevisions) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeControllerRevisions) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(controllerrevisionsResource, c.ns, opts)) } // Create takes the representation of a controllerRevision and creates it. Returns the server's representation of the controllerRevision, and an error, if there is any. -func (c *FakeControllerRevisions) Create(ctx context.Context, controllerRevision *appsv1.ControllerRevision, opts v1.CreateOptions) (result *appsv1.ControllerRevision, err error) { +func (c *FakeControllerRevisions) Create(ctx context.Context, controllerRevision *v1.ControllerRevision, opts metav1.CreateOptions) (result *v1.ControllerRevision, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(controllerrevisionsResource, c.ns, controllerRevision), &appsv1.ControllerRevision{}) + Invokes(testing.NewCreateAction(controllerrevisionsResource, c.ns, controllerRevision), &v1.ControllerRevision{}) if obj == nil { return nil, err } - return obj.(*appsv1.ControllerRevision), err + return obj.(*v1.ControllerRevision), err } // Update takes the representation of a controllerRevision and updates it. Returns the server's representation of the controllerRevision, and an error, if there is any. -func (c *FakeControllerRevisions) Update(ctx context.Context, controllerRevision *appsv1.ControllerRevision, opts v1.UpdateOptions) (result *appsv1.ControllerRevision, err error) { +func (c *FakeControllerRevisions) Update(ctx context.Context, controllerRevision *v1.ControllerRevision, opts metav1.UpdateOptions) (result *v1.ControllerRevision, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(controllerrevisionsResource, c.ns, controllerRevision), &appsv1.ControllerRevision{}) + Invokes(testing.NewUpdateAction(controllerrevisionsResource, c.ns, controllerRevision), &v1.ControllerRevision{}) if obj == nil { return nil, err } - return obj.(*appsv1.ControllerRevision), err + return obj.(*v1.ControllerRevision), err } // Delete takes name of the controllerRevision and deletes it. Returns an error if one occurs. -func (c *FakeControllerRevisions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeControllerRevisions) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(controllerrevisionsResource, c.ns, name, opts), &appsv1.ControllerRevision{}) + Invokes(testing.NewDeleteActionWithOptions(controllerrevisionsResource, c.ns, name, opts), &v1.ControllerRevision{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeControllerRevisions) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeControllerRevisions) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(controllerrevisionsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &appsv1.ControllerRevisionList{}) + _, err := c.Fake.Invokes(action, &v1.ControllerRevisionList{}) return err } // Patch applies the patch and returns the patched controllerRevision. -func (c *FakeControllerRevisions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *appsv1.ControllerRevision, err error) { +func (c *FakeControllerRevisions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ControllerRevision, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(controllerrevisionsResource, c.ns, name, pt, data, subresources...), &appsv1.ControllerRevision{}) + Invokes(testing.NewPatchSubresourceAction(controllerrevisionsResource, c.ns, name, pt, data, subresources...), &v1.ControllerRevision{}) if obj == nil { return nil, err } - return obj.(*appsv1.ControllerRevision), err + return obj.(*v1.ControllerRevision), err } // Apply takes the given apply declarative configuration, applies it and returns the applied controllerRevision. -func (c *FakeControllerRevisions) Apply(ctx context.Context, controllerRevision *applyconfigurationsappsv1.ControllerRevisionApplyConfiguration, opts v1.ApplyOptions) (result *appsv1.ControllerRevision, err error) { +func (c *FakeControllerRevisions) Apply(ctx context.Context, controllerRevision *appsv1.ControllerRevisionApplyConfiguration, opts metav1.ApplyOptions) (result *v1.ControllerRevision, err error) { if controllerRevision == nil { return nil, fmt.Errorf("controllerRevision provided to Apply must not be nil") } @@ -146,10 +145,10 @@ func (c *FakeControllerRevisions) Apply(ctx context.Context, controllerRevision return nil, fmt.Errorf("controllerRevision.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(controllerrevisionsResource, c.ns, *name, types.ApplyPatchType, data), &appsv1.ControllerRevision{}) + Invokes(testing.NewPatchSubresourceAction(controllerrevisionsResource, c.ns, *name, types.ApplyPatchType, data), &v1.ControllerRevision{}) if obj == nil { return nil, err } - return obj.(*appsv1.ControllerRevision), err + return obj.(*v1.ControllerRevision), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_daemonset.go b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_daemonset.go index 00c28df9ba..3e0df72352 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_daemonset.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_daemonset.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - appsv1 "k8s.io/api/apps/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsappsv1 "k8s.io/client-go/applyconfigurations/apps/v1" + appsv1 "k8s.io/client-go/applyconfigurations/apps/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeDaemonSets struct { ns string } -var daemonsetsResource = schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "daemonsets"} +var daemonsetsResource = v1.SchemeGroupVersion.WithResource("daemonsets") -var daemonsetsKind = schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "DaemonSet"} +var daemonsetsKind = v1.SchemeGroupVersion.WithKind("DaemonSet") // Get takes name of the daemonSet, and returns the corresponding daemonSet object, and an error if there is any. -func (c *FakeDaemonSets) Get(ctx context.Context, name string, options v1.GetOptions) (result *appsv1.DaemonSet, err error) { +func (c *FakeDaemonSets) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.DaemonSet, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(daemonsetsResource, c.ns, name), &appsv1.DaemonSet{}) + Invokes(testing.NewGetAction(daemonsetsResource, c.ns, name), &v1.DaemonSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.DaemonSet), err + return obj.(*v1.DaemonSet), err } // List takes label and field selectors, and returns the list of DaemonSets that match those selectors. -func (c *FakeDaemonSets) List(ctx context.Context, opts v1.ListOptions) (result *appsv1.DaemonSetList, err error) { +func (c *FakeDaemonSets) List(ctx context.Context, opts metav1.ListOptions) (result *v1.DaemonSetList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(daemonsetsResource, daemonsetsKind, c.ns, opts), &appsv1.DaemonSetList{}) + Invokes(testing.NewListAction(daemonsetsResource, daemonsetsKind, c.ns, opts), &v1.DaemonSetList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeDaemonSets) List(ctx context.Context, opts v1.ListOptions) (result if label == nil { label = labels.Everything() } - list := &appsv1.DaemonSetList{ListMeta: obj.(*appsv1.DaemonSetList).ListMeta} - for _, item := range obj.(*appsv1.DaemonSetList).Items { + list := &v1.DaemonSetList{ListMeta: obj.(*v1.DaemonSetList).ListMeta} + for _, item := range obj.(*v1.DaemonSetList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,75 +76,75 @@ func (c *FakeDaemonSets) List(ctx context.Context, opts v1.ListOptions) (result } // Watch returns a watch.Interface that watches the requested daemonSets. -func (c *FakeDaemonSets) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeDaemonSets) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(daemonsetsResource, c.ns, opts)) } // 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(ctx context.Context, daemonSet *appsv1.DaemonSet, opts v1.CreateOptions) (result *appsv1.DaemonSet, err error) { +func (c *FakeDaemonSets) Create(ctx context.Context, daemonSet *v1.DaemonSet, opts metav1.CreateOptions) (result *v1.DaemonSet, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(daemonsetsResource, c.ns, daemonSet), &appsv1.DaemonSet{}) + Invokes(testing.NewCreateAction(daemonsetsResource, c.ns, daemonSet), &v1.DaemonSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.DaemonSet), err + return obj.(*v1.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(ctx context.Context, daemonSet *appsv1.DaemonSet, opts v1.UpdateOptions) (result *appsv1.DaemonSet, err error) { +func (c *FakeDaemonSets) Update(ctx context.Context, daemonSet *v1.DaemonSet, opts metav1.UpdateOptions) (result *v1.DaemonSet, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(daemonsetsResource, c.ns, daemonSet), &appsv1.DaemonSet{}) + Invokes(testing.NewUpdateAction(daemonsetsResource, c.ns, daemonSet), &v1.DaemonSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.DaemonSet), err + return obj.(*v1.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(ctx context.Context, daemonSet *appsv1.DaemonSet, opts v1.UpdateOptions) (*appsv1.DaemonSet, error) { +func (c *FakeDaemonSets) UpdateStatus(ctx context.Context, daemonSet *v1.DaemonSet, opts metav1.UpdateOptions) (*v1.DaemonSet, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(daemonsetsResource, "status", c.ns, daemonSet), &appsv1.DaemonSet{}) + Invokes(testing.NewUpdateSubresourceAction(daemonsetsResource, "status", c.ns, daemonSet), &v1.DaemonSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.DaemonSet), err + return obj.(*v1.DaemonSet), err } // Delete takes name of the daemonSet and deletes it. Returns an error if one occurs. -func (c *FakeDaemonSets) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeDaemonSets) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(daemonsetsResource, c.ns, name, opts), &appsv1.DaemonSet{}) + Invokes(testing.NewDeleteActionWithOptions(daemonsetsResource, c.ns, name, opts), &v1.DaemonSet{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeDaemonSets) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeDaemonSets) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(daemonsetsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &appsv1.DaemonSetList{}) + _, err := c.Fake.Invokes(action, &v1.DaemonSetList{}) return err } // Patch applies the patch and returns the patched daemonSet. -func (c *FakeDaemonSets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *appsv1.DaemonSet, err error) { +func (c *FakeDaemonSets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.DaemonSet, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(daemonsetsResource, c.ns, name, pt, data, subresources...), &appsv1.DaemonSet{}) + Invokes(testing.NewPatchSubresourceAction(daemonsetsResource, c.ns, name, pt, data, subresources...), &v1.DaemonSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.DaemonSet), err + return obj.(*v1.DaemonSet), err } // Apply takes the given apply declarative configuration, applies it and returns the applied daemonSet. -func (c *FakeDaemonSets) Apply(ctx context.Context, daemonSet *applyconfigurationsappsv1.DaemonSetApplyConfiguration, opts v1.ApplyOptions) (result *appsv1.DaemonSet, err error) { +func (c *FakeDaemonSets) Apply(ctx context.Context, daemonSet *appsv1.DaemonSetApplyConfiguration, opts metav1.ApplyOptions) (result *v1.DaemonSet, err error) { if daemonSet == nil { return nil, fmt.Errorf("daemonSet provided to Apply must not be nil") } @@ -158,17 +157,17 @@ func (c *FakeDaemonSets) Apply(ctx context.Context, daemonSet *applyconfiguratio return nil, fmt.Errorf("daemonSet.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(daemonsetsResource, c.ns, *name, types.ApplyPatchType, data), &appsv1.DaemonSet{}) + Invokes(testing.NewPatchSubresourceAction(daemonsetsResource, c.ns, *name, types.ApplyPatchType, data), &v1.DaemonSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.DaemonSet), err + return obj.(*v1.DaemonSet), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeDaemonSets) ApplyStatus(ctx context.Context, daemonSet *applyconfigurationsappsv1.DaemonSetApplyConfiguration, opts v1.ApplyOptions) (result *appsv1.DaemonSet, err error) { +func (c *FakeDaemonSets) ApplyStatus(ctx context.Context, daemonSet *appsv1.DaemonSetApplyConfiguration, opts metav1.ApplyOptions) (result *v1.DaemonSet, err error) { if daemonSet == nil { return nil, fmt.Errorf("daemonSet provided to Apply must not be nil") } @@ -181,10 +180,10 @@ func (c *FakeDaemonSets) ApplyStatus(ctx context.Context, daemonSet *applyconfig return nil, fmt.Errorf("daemonSet.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(daemonsetsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &appsv1.DaemonSet{}) + Invokes(testing.NewPatchSubresourceAction(daemonsetsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.DaemonSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.DaemonSet), err + return obj.(*v1.DaemonSet), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_deployment.go b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_deployment.go index 8899824aa5..da1896fe60 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_deployment.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_deployment.go @@ -23,14 +23,13 @@ import ( json "encoding/json" "fmt" - appsv1 "k8s.io/api/apps/v1" + v1 "k8s.io/api/apps/v1" autoscalingv1 "k8s.io/api/autoscaling/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsappsv1 "k8s.io/client-go/applyconfigurations/apps/v1" + appsv1 "k8s.io/client-go/applyconfigurations/apps/v1" applyconfigurationsautoscalingv1 "k8s.io/client-go/applyconfigurations/autoscaling/v1" testing "k8s.io/client-go/testing" ) @@ -41,25 +40,25 @@ type FakeDeployments struct { ns string } -var deploymentsResource = schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"} +var deploymentsResource = v1.SchemeGroupVersion.WithResource("deployments") -var deploymentsKind = schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"} +var deploymentsKind = v1.SchemeGroupVersion.WithKind("Deployment") // Get takes name of the deployment, and returns the corresponding deployment object, and an error if there is any. -func (c *FakeDeployments) Get(ctx context.Context, name string, options v1.GetOptions) (result *appsv1.Deployment, err error) { +func (c *FakeDeployments) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Deployment, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(deploymentsResource, c.ns, name), &appsv1.Deployment{}) + Invokes(testing.NewGetAction(deploymentsResource, c.ns, name), &v1.Deployment{}) if obj == nil { return nil, err } - return obj.(*appsv1.Deployment), err + return obj.(*v1.Deployment), err } // List takes label and field selectors, and returns the list of Deployments that match those selectors. -func (c *FakeDeployments) List(ctx context.Context, opts v1.ListOptions) (result *appsv1.DeploymentList, err error) { +func (c *FakeDeployments) List(ctx context.Context, opts metav1.ListOptions) (result *v1.DeploymentList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(deploymentsResource, deploymentsKind, c.ns, opts), &appsv1.DeploymentList{}) + Invokes(testing.NewListAction(deploymentsResource, deploymentsKind, c.ns, opts), &v1.DeploymentList{}) if obj == nil { return nil, err @@ -69,8 +68,8 @@ func (c *FakeDeployments) List(ctx context.Context, opts v1.ListOptions) (result if label == nil { label = labels.Everything() } - list := &appsv1.DeploymentList{ListMeta: obj.(*appsv1.DeploymentList).ListMeta} - for _, item := range obj.(*appsv1.DeploymentList).Items { + list := &v1.DeploymentList{ListMeta: obj.(*v1.DeploymentList).ListMeta} + for _, item := range obj.(*v1.DeploymentList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -79,75 +78,75 @@ func (c *FakeDeployments) List(ctx context.Context, opts v1.ListOptions) (result } // Watch returns a watch.Interface that watches the requested deployments. -func (c *FakeDeployments) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeDeployments) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(deploymentsResource, c.ns, opts)) } // 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(ctx context.Context, deployment *appsv1.Deployment, opts v1.CreateOptions) (result *appsv1.Deployment, err error) { +func (c *FakeDeployments) Create(ctx context.Context, deployment *v1.Deployment, opts metav1.CreateOptions) (result *v1.Deployment, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(deploymentsResource, c.ns, deployment), &appsv1.Deployment{}) + Invokes(testing.NewCreateAction(deploymentsResource, c.ns, deployment), &v1.Deployment{}) if obj == nil { return nil, err } - return obj.(*appsv1.Deployment), err + return obj.(*v1.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(ctx context.Context, deployment *appsv1.Deployment, opts v1.UpdateOptions) (result *appsv1.Deployment, err error) { +func (c *FakeDeployments) Update(ctx context.Context, deployment *v1.Deployment, opts metav1.UpdateOptions) (result *v1.Deployment, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(deploymentsResource, c.ns, deployment), &appsv1.Deployment{}) + Invokes(testing.NewUpdateAction(deploymentsResource, c.ns, deployment), &v1.Deployment{}) if obj == nil { return nil, err } - return obj.(*appsv1.Deployment), err + return obj.(*v1.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(ctx context.Context, deployment *appsv1.Deployment, opts v1.UpdateOptions) (*appsv1.Deployment, error) { +func (c *FakeDeployments) UpdateStatus(ctx context.Context, deployment *v1.Deployment, opts metav1.UpdateOptions) (*v1.Deployment, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(deploymentsResource, "status", c.ns, deployment), &appsv1.Deployment{}) + Invokes(testing.NewUpdateSubresourceAction(deploymentsResource, "status", c.ns, deployment), &v1.Deployment{}) if obj == nil { return nil, err } - return obj.(*appsv1.Deployment), err + return obj.(*v1.Deployment), err } // Delete takes name of the deployment and deletes it. Returns an error if one occurs. -func (c *FakeDeployments) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeDeployments) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(deploymentsResource, c.ns, name, opts), &appsv1.Deployment{}) + Invokes(testing.NewDeleteActionWithOptions(deploymentsResource, c.ns, name, opts), &v1.Deployment{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeDeployments) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeDeployments) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(deploymentsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &appsv1.DeploymentList{}) + _, err := c.Fake.Invokes(action, &v1.DeploymentList{}) return err } // Patch applies the patch and returns the patched deployment. -func (c *FakeDeployments) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *appsv1.Deployment, err error) { +func (c *FakeDeployments) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Deployment, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(deploymentsResource, c.ns, name, pt, data, subresources...), &appsv1.Deployment{}) + Invokes(testing.NewPatchSubresourceAction(deploymentsResource, c.ns, name, pt, data, subresources...), &v1.Deployment{}) if obj == nil { return nil, err } - return obj.(*appsv1.Deployment), err + return obj.(*v1.Deployment), err } // Apply takes the given apply declarative configuration, applies it and returns the applied deployment. -func (c *FakeDeployments) Apply(ctx context.Context, deployment *applyconfigurationsappsv1.DeploymentApplyConfiguration, opts v1.ApplyOptions) (result *appsv1.Deployment, err error) { +func (c *FakeDeployments) Apply(ctx context.Context, deployment *appsv1.DeploymentApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Deployment, err error) { if deployment == nil { return nil, fmt.Errorf("deployment provided to Apply must not be nil") } @@ -160,17 +159,17 @@ func (c *FakeDeployments) Apply(ctx context.Context, deployment *applyconfigurat return nil, fmt.Errorf("deployment.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(deploymentsResource, c.ns, *name, types.ApplyPatchType, data), &appsv1.Deployment{}) + Invokes(testing.NewPatchSubresourceAction(deploymentsResource, c.ns, *name, types.ApplyPatchType, data), &v1.Deployment{}) if obj == nil { return nil, err } - return obj.(*appsv1.Deployment), err + return obj.(*v1.Deployment), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeDeployments) ApplyStatus(ctx context.Context, deployment *applyconfigurationsappsv1.DeploymentApplyConfiguration, opts v1.ApplyOptions) (result *appsv1.Deployment, err error) { +func (c *FakeDeployments) ApplyStatus(ctx context.Context, deployment *appsv1.DeploymentApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Deployment, err error) { if deployment == nil { return nil, fmt.Errorf("deployment provided to Apply must not be nil") } @@ -183,16 +182,16 @@ func (c *FakeDeployments) ApplyStatus(ctx context.Context, deployment *applyconf return nil, fmt.Errorf("deployment.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(deploymentsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &appsv1.Deployment{}) + Invokes(testing.NewPatchSubresourceAction(deploymentsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.Deployment{}) if obj == nil { return nil, err } - return obj.(*appsv1.Deployment), err + return obj.(*v1.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(ctx context.Context, deploymentName string, options v1.GetOptions) (result *autoscalingv1.Scale, err error) { +func (c *FakeDeployments) GetScale(ctx context.Context, deploymentName string, options metav1.GetOptions) (result *autoscalingv1.Scale, err error) { obj, err := c.Fake. Invokes(testing.NewGetSubresourceAction(deploymentsResource, c.ns, "scale", deploymentName), &autoscalingv1.Scale{}) @@ -203,7 +202,7 @@ func (c *FakeDeployments) GetScale(ctx context.Context, deploymentName string, o } // 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(ctx context.Context, deploymentName string, scale *autoscalingv1.Scale, opts v1.UpdateOptions) (result *autoscalingv1.Scale, err error) { +func (c *FakeDeployments) UpdateScale(ctx context.Context, deploymentName string, scale *autoscalingv1.Scale, opts metav1.UpdateOptions) (result *autoscalingv1.Scale, err error) { obj, err := c.Fake. Invokes(testing.NewUpdateSubresourceAction(deploymentsResource, "scale", c.ns, scale), &autoscalingv1.Scale{}) @@ -215,7 +214,7 @@ func (c *FakeDeployments) UpdateScale(ctx context.Context, deploymentName string // ApplyScale takes top resource name and the apply declarative configuration for scale, // applies it and returns the applied scale, and an error, if there is any. -func (c *FakeDeployments) ApplyScale(ctx context.Context, deploymentName string, scale *applyconfigurationsautoscalingv1.ScaleApplyConfiguration, opts v1.ApplyOptions) (result *autoscalingv1.Scale, err error) { +func (c *FakeDeployments) ApplyScale(ctx context.Context, deploymentName string, scale *applyconfigurationsautoscalingv1.ScaleApplyConfiguration, opts metav1.ApplyOptions) (result *autoscalingv1.Scale, err error) { if scale == nil { return nil, fmt.Errorf("scale provided to ApplyScale must not be nil") } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_replicaset.go b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_replicaset.go index 39acfafeb2..dedf19b42f 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_replicaset.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_replicaset.go @@ -23,14 +23,13 @@ import ( json "encoding/json" "fmt" - appsv1 "k8s.io/api/apps/v1" + v1 "k8s.io/api/apps/v1" autoscalingv1 "k8s.io/api/autoscaling/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsappsv1 "k8s.io/client-go/applyconfigurations/apps/v1" + appsv1 "k8s.io/client-go/applyconfigurations/apps/v1" applyconfigurationsautoscalingv1 "k8s.io/client-go/applyconfigurations/autoscaling/v1" testing "k8s.io/client-go/testing" ) @@ -41,25 +40,25 @@ type FakeReplicaSets struct { ns string } -var replicasetsResource = schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "replicasets"} +var replicasetsResource = v1.SchemeGroupVersion.WithResource("replicasets") -var replicasetsKind = schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "ReplicaSet"} +var replicasetsKind = v1.SchemeGroupVersion.WithKind("ReplicaSet") // Get takes name of the replicaSet, and returns the corresponding replicaSet object, and an error if there is any. -func (c *FakeReplicaSets) Get(ctx context.Context, name string, options v1.GetOptions) (result *appsv1.ReplicaSet, err error) { +func (c *FakeReplicaSets) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ReplicaSet, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(replicasetsResource, c.ns, name), &appsv1.ReplicaSet{}) + Invokes(testing.NewGetAction(replicasetsResource, c.ns, name), &v1.ReplicaSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.ReplicaSet), err + return obj.(*v1.ReplicaSet), err } // List takes label and field selectors, and returns the list of ReplicaSets that match those selectors. -func (c *FakeReplicaSets) List(ctx context.Context, opts v1.ListOptions) (result *appsv1.ReplicaSetList, err error) { +func (c *FakeReplicaSets) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ReplicaSetList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(replicasetsResource, replicasetsKind, c.ns, opts), &appsv1.ReplicaSetList{}) + Invokes(testing.NewListAction(replicasetsResource, replicasetsKind, c.ns, opts), &v1.ReplicaSetList{}) if obj == nil { return nil, err @@ -69,8 +68,8 @@ func (c *FakeReplicaSets) List(ctx context.Context, opts v1.ListOptions) (result if label == nil { label = labels.Everything() } - list := &appsv1.ReplicaSetList{ListMeta: obj.(*appsv1.ReplicaSetList).ListMeta} - for _, item := range obj.(*appsv1.ReplicaSetList).Items { + list := &v1.ReplicaSetList{ListMeta: obj.(*v1.ReplicaSetList).ListMeta} + for _, item := range obj.(*v1.ReplicaSetList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -79,75 +78,75 @@ func (c *FakeReplicaSets) List(ctx context.Context, opts v1.ListOptions) (result } // Watch returns a watch.Interface that watches the requested replicaSets. -func (c *FakeReplicaSets) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeReplicaSets) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(replicasetsResource, c.ns, opts)) } // 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(ctx context.Context, replicaSet *appsv1.ReplicaSet, opts v1.CreateOptions) (result *appsv1.ReplicaSet, err error) { +func (c *FakeReplicaSets) Create(ctx context.Context, replicaSet *v1.ReplicaSet, opts metav1.CreateOptions) (result *v1.ReplicaSet, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(replicasetsResource, c.ns, replicaSet), &appsv1.ReplicaSet{}) + Invokes(testing.NewCreateAction(replicasetsResource, c.ns, replicaSet), &v1.ReplicaSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.ReplicaSet), err + return obj.(*v1.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(ctx context.Context, replicaSet *appsv1.ReplicaSet, opts v1.UpdateOptions) (result *appsv1.ReplicaSet, err error) { +func (c *FakeReplicaSets) Update(ctx context.Context, replicaSet *v1.ReplicaSet, opts metav1.UpdateOptions) (result *v1.ReplicaSet, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(replicasetsResource, c.ns, replicaSet), &appsv1.ReplicaSet{}) + Invokes(testing.NewUpdateAction(replicasetsResource, c.ns, replicaSet), &v1.ReplicaSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.ReplicaSet), err + return obj.(*v1.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(ctx context.Context, replicaSet *appsv1.ReplicaSet, opts v1.UpdateOptions) (*appsv1.ReplicaSet, error) { +func (c *FakeReplicaSets) UpdateStatus(ctx context.Context, replicaSet *v1.ReplicaSet, opts metav1.UpdateOptions) (*v1.ReplicaSet, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(replicasetsResource, "status", c.ns, replicaSet), &appsv1.ReplicaSet{}) + Invokes(testing.NewUpdateSubresourceAction(replicasetsResource, "status", c.ns, replicaSet), &v1.ReplicaSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.ReplicaSet), err + return obj.(*v1.ReplicaSet), err } // Delete takes name of the replicaSet and deletes it. Returns an error if one occurs. -func (c *FakeReplicaSets) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeReplicaSets) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(replicasetsResource, c.ns, name, opts), &appsv1.ReplicaSet{}) + Invokes(testing.NewDeleteActionWithOptions(replicasetsResource, c.ns, name, opts), &v1.ReplicaSet{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeReplicaSets) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeReplicaSets) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(replicasetsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &appsv1.ReplicaSetList{}) + _, err := c.Fake.Invokes(action, &v1.ReplicaSetList{}) return err } // Patch applies the patch and returns the patched replicaSet. -func (c *FakeReplicaSets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *appsv1.ReplicaSet, err error) { +func (c *FakeReplicaSets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ReplicaSet, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(replicasetsResource, c.ns, name, pt, data, subresources...), &appsv1.ReplicaSet{}) + Invokes(testing.NewPatchSubresourceAction(replicasetsResource, c.ns, name, pt, data, subresources...), &v1.ReplicaSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.ReplicaSet), err + return obj.(*v1.ReplicaSet), err } // Apply takes the given apply declarative configuration, applies it and returns the applied replicaSet. -func (c *FakeReplicaSets) Apply(ctx context.Context, replicaSet *applyconfigurationsappsv1.ReplicaSetApplyConfiguration, opts v1.ApplyOptions) (result *appsv1.ReplicaSet, err error) { +func (c *FakeReplicaSets) Apply(ctx context.Context, replicaSet *appsv1.ReplicaSetApplyConfiguration, opts metav1.ApplyOptions) (result *v1.ReplicaSet, err error) { if replicaSet == nil { return nil, fmt.Errorf("replicaSet provided to Apply must not be nil") } @@ -160,17 +159,17 @@ func (c *FakeReplicaSets) Apply(ctx context.Context, replicaSet *applyconfigurat return nil, fmt.Errorf("replicaSet.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(replicasetsResource, c.ns, *name, types.ApplyPatchType, data), &appsv1.ReplicaSet{}) + Invokes(testing.NewPatchSubresourceAction(replicasetsResource, c.ns, *name, types.ApplyPatchType, data), &v1.ReplicaSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.ReplicaSet), err + return obj.(*v1.ReplicaSet), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeReplicaSets) ApplyStatus(ctx context.Context, replicaSet *applyconfigurationsappsv1.ReplicaSetApplyConfiguration, opts v1.ApplyOptions) (result *appsv1.ReplicaSet, err error) { +func (c *FakeReplicaSets) ApplyStatus(ctx context.Context, replicaSet *appsv1.ReplicaSetApplyConfiguration, opts metav1.ApplyOptions) (result *v1.ReplicaSet, err error) { if replicaSet == nil { return nil, fmt.Errorf("replicaSet provided to Apply must not be nil") } @@ -183,16 +182,16 @@ func (c *FakeReplicaSets) ApplyStatus(ctx context.Context, replicaSet *applyconf return nil, fmt.Errorf("replicaSet.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(replicasetsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &appsv1.ReplicaSet{}) + Invokes(testing.NewPatchSubresourceAction(replicasetsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.ReplicaSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.ReplicaSet), err + return obj.(*v1.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(ctx context.Context, replicaSetName string, options v1.GetOptions) (result *autoscalingv1.Scale, err error) { +func (c *FakeReplicaSets) GetScale(ctx context.Context, replicaSetName string, options metav1.GetOptions) (result *autoscalingv1.Scale, err error) { obj, err := c.Fake. Invokes(testing.NewGetSubresourceAction(replicasetsResource, c.ns, "scale", replicaSetName), &autoscalingv1.Scale{}) @@ -203,7 +202,7 @@ func (c *FakeReplicaSets) GetScale(ctx context.Context, replicaSetName string, o } // 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(ctx context.Context, replicaSetName string, scale *autoscalingv1.Scale, opts v1.UpdateOptions) (result *autoscalingv1.Scale, err error) { +func (c *FakeReplicaSets) UpdateScale(ctx context.Context, replicaSetName string, scale *autoscalingv1.Scale, opts metav1.UpdateOptions) (result *autoscalingv1.Scale, err error) { obj, err := c.Fake. Invokes(testing.NewUpdateSubresourceAction(replicasetsResource, "scale", c.ns, scale), &autoscalingv1.Scale{}) @@ -215,7 +214,7 @@ func (c *FakeReplicaSets) UpdateScale(ctx context.Context, replicaSetName string // ApplyScale takes top resource name and the apply declarative configuration for scale, // applies it and returns the applied scale, and an error, if there is any. -func (c *FakeReplicaSets) ApplyScale(ctx context.Context, replicaSetName string, scale *applyconfigurationsautoscalingv1.ScaleApplyConfiguration, opts v1.ApplyOptions) (result *autoscalingv1.Scale, err error) { +func (c *FakeReplicaSets) ApplyScale(ctx context.Context, replicaSetName string, scale *applyconfigurationsautoscalingv1.ScaleApplyConfiguration, opts metav1.ApplyOptions) (result *autoscalingv1.Scale, err error) { if scale == nil { return nil, fmt.Errorf("scale provided to ApplyScale must not be nil") } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_statefulset.go b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_statefulset.go index e04eb025d4..f1d7d96e8d 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_statefulset.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1/fake/fake_statefulset.go @@ -23,14 +23,13 @@ import ( json "encoding/json" "fmt" - appsv1 "k8s.io/api/apps/v1" + v1 "k8s.io/api/apps/v1" autoscalingv1 "k8s.io/api/autoscaling/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsappsv1 "k8s.io/client-go/applyconfigurations/apps/v1" + appsv1 "k8s.io/client-go/applyconfigurations/apps/v1" applyconfigurationsautoscalingv1 "k8s.io/client-go/applyconfigurations/autoscaling/v1" testing "k8s.io/client-go/testing" ) @@ -41,25 +40,25 @@ type FakeStatefulSets struct { ns string } -var statefulsetsResource = schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "statefulsets"} +var statefulsetsResource = v1.SchemeGroupVersion.WithResource("statefulsets") -var statefulsetsKind = schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "StatefulSet"} +var statefulsetsKind = v1.SchemeGroupVersion.WithKind("StatefulSet") // Get takes name of the statefulSet, and returns the corresponding statefulSet object, and an error if there is any. -func (c *FakeStatefulSets) Get(ctx context.Context, name string, options v1.GetOptions) (result *appsv1.StatefulSet, err error) { +func (c *FakeStatefulSets) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.StatefulSet, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(statefulsetsResource, c.ns, name), &appsv1.StatefulSet{}) + Invokes(testing.NewGetAction(statefulsetsResource, c.ns, name), &v1.StatefulSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.StatefulSet), err + return obj.(*v1.StatefulSet), err } // List takes label and field selectors, and returns the list of StatefulSets that match those selectors. -func (c *FakeStatefulSets) List(ctx context.Context, opts v1.ListOptions) (result *appsv1.StatefulSetList, err error) { +func (c *FakeStatefulSets) List(ctx context.Context, opts metav1.ListOptions) (result *v1.StatefulSetList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(statefulsetsResource, statefulsetsKind, c.ns, opts), &appsv1.StatefulSetList{}) + Invokes(testing.NewListAction(statefulsetsResource, statefulsetsKind, c.ns, opts), &v1.StatefulSetList{}) if obj == nil { return nil, err @@ -69,8 +68,8 @@ func (c *FakeStatefulSets) List(ctx context.Context, opts v1.ListOptions) (resul if label == nil { label = labels.Everything() } - list := &appsv1.StatefulSetList{ListMeta: obj.(*appsv1.StatefulSetList).ListMeta} - for _, item := range obj.(*appsv1.StatefulSetList).Items { + list := &v1.StatefulSetList{ListMeta: obj.(*v1.StatefulSetList).ListMeta} + for _, item := range obj.(*v1.StatefulSetList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -79,75 +78,75 @@ func (c *FakeStatefulSets) List(ctx context.Context, opts v1.ListOptions) (resul } // Watch returns a watch.Interface that watches the requested statefulSets. -func (c *FakeStatefulSets) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeStatefulSets) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(statefulsetsResource, c.ns, opts)) } // Create takes the representation of a statefulSet and creates it. Returns the server's representation of the statefulSet, and an error, if there is any. -func (c *FakeStatefulSets) Create(ctx context.Context, statefulSet *appsv1.StatefulSet, opts v1.CreateOptions) (result *appsv1.StatefulSet, err error) { +func (c *FakeStatefulSets) Create(ctx context.Context, statefulSet *v1.StatefulSet, opts metav1.CreateOptions) (result *v1.StatefulSet, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(statefulsetsResource, c.ns, statefulSet), &appsv1.StatefulSet{}) + Invokes(testing.NewCreateAction(statefulsetsResource, c.ns, statefulSet), &v1.StatefulSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.StatefulSet), err + return obj.(*v1.StatefulSet), err } // Update takes the representation of a statefulSet and updates it. Returns the server's representation of the statefulSet, and an error, if there is any. -func (c *FakeStatefulSets) Update(ctx context.Context, statefulSet *appsv1.StatefulSet, opts v1.UpdateOptions) (result *appsv1.StatefulSet, err error) { +func (c *FakeStatefulSets) Update(ctx context.Context, statefulSet *v1.StatefulSet, opts metav1.UpdateOptions) (result *v1.StatefulSet, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(statefulsetsResource, c.ns, statefulSet), &appsv1.StatefulSet{}) + Invokes(testing.NewUpdateAction(statefulsetsResource, c.ns, statefulSet), &v1.StatefulSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.StatefulSet), err + return obj.(*v1.StatefulSet), 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 *FakeStatefulSets) UpdateStatus(ctx context.Context, statefulSet *appsv1.StatefulSet, opts v1.UpdateOptions) (*appsv1.StatefulSet, error) { +func (c *FakeStatefulSets) UpdateStatus(ctx context.Context, statefulSet *v1.StatefulSet, opts metav1.UpdateOptions) (*v1.StatefulSet, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(statefulsetsResource, "status", c.ns, statefulSet), &appsv1.StatefulSet{}) + Invokes(testing.NewUpdateSubresourceAction(statefulsetsResource, "status", c.ns, statefulSet), &v1.StatefulSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.StatefulSet), err + return obj.(*v1.StatefulSet), err } // Delete takes name of the statefulSet and deletes it. Returns an error if one occurs. -func (c *FakeStatefulSets) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeStatefulSets) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(statefulsetsResource, c.ns, name, opts), &appsv1.StatefulSet{}) + Invokes(testing.NewDeleteActionWithOptions(statefulsetsResource, c.ns, name, opts), &v1.StatefulSet{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeStatefulSets) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeStatefulSets) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(statefulsetsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &appsv1.StatefulSetList{}) + _, err := c.Fake.Invokes(action, &v1.StatefulSetList{}) return err } // Patch applies the patch and returns the patched statefulSet. -func (c *FakeStatefulSets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *appsv1.StatefulSet, err error) { +func (c *FakeStatefulSets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.StatefulSet, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(statefulsetsResource, c.ns, name, pt, data, subresources...), &appsv1.StatefulSet{}) + Invokes(testing.NewPatchSubresourceAction(statefulsetsResource, c.ns, name, pt, data, subresources...), &v1.StatefulSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.StatefulSet), err + return obj.(*v1.StatefulSet), err } // Apply takes the given apply declarative configuration, applies it and returns the applied statefulSet. -func (c *FakeStatefulSets) Apply(ctx context.Context, statefulSet *applyconfigurationsappsv1.StatefulSetApplyConfiguration, opts v1.ApplyOptions) (result *appsv1.StatefulSet, err error) { +func (c *FakeStatefulSets) Apply(ctx context.Context, statefulSet *appsv1.StatefulSetApplyConfiguration, opts metav1.ApplyOptions) (result *v1.StatefulSet, err error) { if statefulSet == nil { return nil, fmt.Errorf("statefulSet provided to Apply must not be nil") } @@ -160,17 +159,17 @@ func (c *FakeStatefulSets) Apply(ctx context.Context, statefulSet *applyconfigur return nil, fmt.Errorf("statefulSet.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(statefulsetsResource, c.ns, *name, types.ApplyPatchType, data), &appsv1.StatefulSet{}) + Invokes(testing.NewPatchSubresourceAction(statefulsetsResource, c.ns, *name, types.ApplyPatchType, data), &v1.StatefulSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.StatefulSet), err + return obj.(*v1.StatefulSet), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeStatefulSets) ApplyStatus(ctx context.Context, statefulSet *applyconfigurationsappsv1.StatefulSetApplyConfiguration, opts v1.ApplyOptions) (result *appsv1.StatefulSet, err error) { +func (c *FakeStatefulSets) ApplyStatus(ctx context.Context, statefulSet *appsv1.StatefulSetApplyConfiguration, opts metav1.ApplyOptions) (result *v1.StatefulSet, err error) { if statefulSet == nil { return nil, fmt.Errorf("statefulSet provided to Apply must not be nil") } @@ -183,16 +182,16 @@ func (c *FakeStatefulSets) ApplyStatus(ctx context.Context, statefulSet *applyco return nil, fmt.Errorf("statefulSet.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(statefulsetsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &appsv1.StatefulSet{}) + Invokes(testing.NewPatchSubresourceAction(statefulsetsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.StatefulSet{}) if obj == nil { return nil, err } - return obj.(*appsv1.StatefulSet), err + return obj.(*v1.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(ctx context.Context, statefulSetName string, options v1.GetOptions) (result *autoscalingv1.Scale, err error) { +func (c *FakeStatefulSets) GetScale(ctx context.Context, statefulSetName string, options metav1.GetOptions) (result *autoscalingv1.Scale, err error) { obj, err := c.Fake. Invokes(testing.NewGetSubresourceAction(statefulsetsResource, c.ns, "scale", statefulSetName), &autoscalingv1.Scale{}) @@ -203,7 +202,7 @@ func (c *FakeStatefulSets) GetScale(ctx context.Context, statefulSetName string, } // 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(ctx context.Context, statefulSetName string, scale *autoscalingv1.Scale, opts v1.UpdateOptions) (result *autoscalingv1.Scale, err error) { +func (c *FakeStatefulSets) UpdateScale(ctx context.Context, statefulSetName string, scale *autoscalingv1.Scale, opts metav1.UpdateOptions) (result *autoscalingv1.Scale, err error) { obj, err := c.Fake. Invokes(testing.NewUpdateSubresourceAction(statefulsetsResource, "scale", c.ns, scale), &autoscalingv1.Scale{}) @@ -215,7 +214,7 @@ func (c *FakeStatefulSets) UpdateScale(ctx context.Context, statefulSetName stri // ApplyScale takes top resource name and the apply declarative configuration for scale, // applies it and returns the applied scale, and an error, if there is any. -func (c *FakeStatefulSets) ApplyScale(ctx context.Context, statefulSetName string, scale *applyconfigurationsautoscalingv1.ScaleApplyConfiguration, opts v1.ApplyOptions) (result *autoscalingv1.Scale, err error) { +func (c *FakeStatefulSets) ApplyScale(ctx context.Context, statefulSetName string, scale *applyconfigurationsautoscalingv1.ScaleApplyConfiguration, opts metav1.ApplyOptions) (result *autoscalingv1.Scale, err error) { if scale == nil { return nil, fmt.Errorf("scale provided to ApplyScale must not be nil") } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_controllerrevision.go b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_controllerrevision.go index a4fb08c903..1954c94703 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_controllerrevision.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_controllerrevision.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/apps/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" appsv1beta1 "k8s.io/client-go/applyconfigurations/apps/v1beta1" @@ -39,9 +38,9 @@ type FakeControllerRevisions struct { ns string } -var controllerrevisionsResource = schema.GroupVersionResource{Group: "apps", Version: "v1beta1", Resource: "controllerrevisions"} +var controllerrevisionsResource = v1beta1.SchemeGroupVersion.WithResource("controllerrevisions") -var controllerrevisionsKind = schema.GroupVersionKind{Group: "apps", Version: "v1beta1", Kind: "ControllerRevision"} +var controllerrevisionsKind = v1beta1.SchemeGroupVersion.WithKind("ControllerRevision") // Get takes name of the controllerRevision, and returns the corresponding controllerRevision object, and an error if there is any. func (c *FakeControllerRevisions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ControllerRevision, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_deployment.go b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_deployment.go index 2db29b4814..9614852f74 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_deployment.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_deployment.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/apps/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" appsv1beta1 "k8s.io/client-go/applyconfigurations/apps/v1beta1" @@ -39,9 +38,9 @@ type FakeDeployments struct { ns string } -var deploymentsResource = schema.GroupVersionResource{Group: "apps", Version: "v1beta1", Resource: "deployments"} +var deploymentsResource = v1beta1.SchemeGroupVersion.WithResource("deployments") -var deploymentsKind = schema.GroupVersionKind{Group: "apps", Version: "v1beta1", Kind: "Deployment"} +var deploymentsKind = v1beta1.SchemeGroupVersion.WithKind("Deployment") // Get takes name of the deployment, and returns the corresponding deployment object, and an error if there is any. func (c *FakeDeployments) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Deployment, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_statefulset.go b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_statefulset.go index b756a3239c..2124515cfe 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_statefulset.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta1/fake/fake_statefulset.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/apps/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" appsv1beta1 "k8s.io/client-go/applyconfigurations/apps/v1beta1" @@ -39,9 +38,9 @@ type FakeStatefulSets struct { ns string } -var statefulsetsResource = schema.GroupVersionResource{Group: "apps", Version: "v1beta1", Resource: "statefulsets"} +var statefulsetsResource = v1beta1.SchemeGroupVersion.WithResource("statefulsets") -var statefulsetsKind = schema.GroupVersionKind{Group: "apps", Version: "v1beta1", Kind: "StatefulSet"} +var statefulsetsKind = v1beta1.SchemeGroupVersion.WithKind("StatefulSet") // Get takes name of the statefulSet, and returns the corresponding statefulSet object, and an error if there is any. func (c *FakeStatefulSets) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.StatefulSet, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_controllerrevision.go b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_controllerrevision.go index f3d71bf77e..1bf7fb3314 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_controllerrevision.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_controllerrevision.go @@ -26,7 +26,6 @@ import ( v1beta2 "k8s.io/api/apps/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" appsv1beta2 "k8s.io/client-go/applyconfigurations/apps/v1beta2" @@ -39,9 +38,9 @@ type FakeControllerRevisions struct { ns string } -var controllerrevisionsResource = schema.GroupVersionResource{Group: "apps", Version: "v1beta2", Resource: "controllerrevisions"} +var controllerrevisionsResource = v1beta2.SchemeGroupVersion.WithResource("controllerrevisions") -var controllerrevisionsKind = schema.GroupVersionKind{Group: "apps", Version: "v1beta2", Kind: "ControllerRevision"} +var controllerrevisionsKind = v1beta2.SchemeGroupVersion.WithKind("ControllerRevision") // Get takes name of the controllerRevision, and returns the corresponding controllerRevision object, and an error if there is any. func (c *FakeControllerRevisions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.ControllerRevision, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_daemonset.go b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_daemonset.go index 3ee0f7239c..8f5cfa5a8a 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_daemonset.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_daemonset.go @@ -26,7 +26,6 @@ import ( v1beta2 "k8s.io/api/apps/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" appsv1beta2 "k8s.io/client-go/applyconfigurations/apps/v1beta2" @@ -39,9 +38,9 @@ type FakeDaemonSets struct { ns string } -var daemonsetsResource = schema.GroupVersionResource{Group: "apps", Version: "v1beta2", Resource: "daemonsets"} +var daemonsetsResource = v1beta2.SchemeGroupVersion.WithResource("daemonsets") -var daemonsetsKind = schema.GroupVersionKind{Group: "apps", Version: "v1beta2", Kind: "DaemonSet"} +var daemonsetsKind = v1beta2.SchemeGroupVersion.WithKind("DaemonSet") // Get takes name of the daemonSet, and returns the corresponding daemonSet object, and an error if there is any. func (c *FakeDaemonSets) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.DaemonSet, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_deployment.go b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_deployment.go index 38fb2a67c7..c9e8ab48bb 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_deployment.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_deployment.go @@ -26,7 +26,6 @@ import ( v1beta2 "k8s.io/api/apps/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" appsv1beta2 "k8s.io/client-go/applyconfigurations/apps/v1beta2" @@ -39,9 +38,9 @@ type FakeDeployments struct { ns string } -var deploymentsResource = schema.GroupVersionResource{Group: "apps", Version: "v1beta2", Resource: "deployments"} +var deploymentsResource = v1beta2.SchemeGroupVersion.WithResource("deployments") -var deploymentsKind = schema.GroupVersionKind{Group: "apps", Version: "v1beta2", Kind: "Deployment"} +var deploymentsKind = v1beta2.SchemeGroupVersion.WithKind("Deployment") // Get takes name of the deployment, and returns the corresponding deployment object, and an error if there is any. func (c *FakeDeployments) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.Deployment, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_replicaset.go b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_replicaset.go index 2fb89cee07..46e1a78a7a 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_replicaset.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_replicaset.go @@ -26,7 +26,6 @@ import ( v1beta2 "k8s.io/api/apps/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" appsv1beta2 "k8s.io/client-go/applyconfigurations/apps/v1beta2" @@ -39,9 +38,9 @@ type FakeReplicaSets struct { ns string } -var replicasetsResource = schema.GroupVersionResource{Group: "apps", Version: "v1beta2", Resource: "replicasets"} +var replicasetsResource = v1beta2.SchemeGroupVersion.WithResource("replicasets") -var replicasetsKind = schema.GroupVersionKind{Group: "apps", Version: "v1beta2", Kind: "ReplicaSet"} +var replicasetsKind = v1beta2.SchemeGroupVersion.WithKind("ReplicaSet") // Get takes name of the replicaSet, and returns the corresponding replicaSet object, and an error if there is any. func (c *FakeReplicaSets) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.ReplicaSet, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_statefulset.go b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_statefulset.go index cc9903c0f5..684f799256 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_statefulset.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta2/fake/fake_statefulset.go @@ -26,7 +26,6 @@ import ( v1beta2 "k8s.io/api/apps/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" appsv1beta2 "k8s.io/client-go/applyconfigurations/apps/v1beta2" @@ -39,9 +38,9 @@ type FakeStatefulSets struct { ns string } -var statefulsetsResource = schema.GroupVersionResource{Group: "apps", Version: "v1beta2", Resource: "statefulsets"} +var statefulsetsResource = v1beta2.SchemeGroupVersion.WithResource("statefulsets") -var statefulsetsKind = schema.GroupVersionKind{Group: "apps", Version: "v1beta2", Kind: "StatefulSet"} +var statefulsetsKind = v1beta2.SchemeGroupVersion.WithKind("StatefulSet") // Get takes name of the statefulSet, and returns the corresponding statefulSet object, and an error if there is any. func (c *FakeStatefulSets) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.StatefulSet, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1/fake/fake_tokenreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1/fake/fake_tokenreview.go index b85fcfbb87..500e87d065 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1/fake/fake_tokenreview.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1/fake/fake_tokenreview.go @@ -23,7 +23,6 @@ import ( v1 "k8s.io/api/authentication/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - schema "k8s.io/apimachinery/pkg/runtime/schema" testing "k8s.io/client-go/testing" ) @@ -32,9 +31,9 @@ type FakeTokenReviews struct { Fake *FakeAuthenticationV1 } -var tokenreviewsResource = schema.GroupVersionResource{Group: "authentication.k8s.io", Version: "v1", Resource: "tokenreviews"} +var tokenreviewsResource = v1.SchemeGroupVersion.WithResource("tokenreviews") -var tokenreviewsKind = schema.GroupVersionKind{Group: "authentication.k8s.io", Version: "v1", Kind: "TokenReview"} +var tokenreviewsKind = v1.SchemeGroupVersion.WithKind("TokenReview") // Create takes the representation of a tokenReview and creates it. Returns the server's representation of the tokenReview, and an error, if there is any. func (c *FakeTokenReviews) Create(ctx context.Context, tokenReview *v1.TokenReview, opts metav1.CreateOptions) (result *v1.TokenReview, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/fake/fake_selfsubjectreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/fake/fake_selfsubjectreview.go index 6bb1c2508e..a20b3dd764 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/fake/fake_selfsubjectreview.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1alpha1/fake/fake_selfsubjectreview.go @@ -23,7 +23,6 @@ import ( v1alpha1 "k8s.io/api/authentication/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - schema "k8s.io/apimachinery/pkg/runtime/schema" testing "k8s.io/client-go/testing" ) @@ -32,9 +31,9 @@ type FakeSelfSubjectReviews struct { Fake *FakeAuthenticationV1alpha1 } -var selfsubjectreviewsResource = schema.GroupVersionResource{Group: "authentication.k8s.io", Version: "v1alpha1", Resource: "selfsubjectreviews"} +var selfsubjectreviewsResource = v1alpha1.SchemeGroupVersion.WithResource("selfsubjectreviews") -var selfsubjectreviewsKind = schema.GroupVersionKind{Group: "authentication.k8s.io", Version: "v1alpha1", Kind: "SelfSubjectReview"} +var selfsubjectreviewsKind = v1alpha1.SchemeGroupVersion.WithKind("SelfSubjectReview") // Create takes the representation of a selfSubjectReview and creates it. Returns the server's representation of the selfSubjectReview, and an error, if there is any. func (c *FakeSelfSubjectReviews) Create(ctx context.Context, selfSubjectReview *v1alpha1.SelfSubjectReview, opts v1.CreateOptions) (result *v1alpha1.SelfSubjectReview, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/authentication_client.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/authentication_client.go index 218cb60c31..7823729e09 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/authentication_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/authentication_client.go @@ -28,6 +28,7 @@ import ( type AuthenticationV1beta1Interface interface { RESTClient() rest.Interface + SelfSubjectReviewsGetter TokenReviewsGetter } @@ -36,6 +37,10 @@ type AuthenticationV1beta1Client struct { restClient rest.Interface } +func (c *AuthenticationV1beta1Client) SelfSubjectReviews() SelfSubjectReviewInterface { + return newSelfSubjectReviews(c) +} + func (c *AuthenticationV1beta1Client) TokenReviews() TokenReviewInterface { return newTokenReviews(c) } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/fake/fake_authentication_client.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/fake/fake_authentication_client.go index 7299653ca2..1d72cf22f6 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/fake/fake_authentication_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/fake/fake_authentication_client.go @@ -28,6 +28,10 @@ type FakeAuthenticationV1beta1 struct { *testing.Fake } +func (c *FakeAuthenticationV1beta1) SelfSubjectReviews() v1beta1.SelfSubjectReviewInterface { + return &FakeSelfSubjectReviews{c} +} + func (c *FakeAuthenticationV1beta1) TokenReviews() v1beta1.TokenReviewInterface { return &FakeTokenReviews{c} } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/fake/fake_selfsubjectreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/fake/fake_selfsubjectreview.go new file mode 100644 index 0000000000..4a9db85cf5 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/fake/fake_selfsubjectreview.go @@ -0,0 +1,46 @@ +/* +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 + +import ( + "context" + + v1beta1 "k8s.io/api/authentication/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + testing "k8s.io/client-go/testing" +) + +// FakeSelfSubjectReviews implements SelfSubjectReviewInterface +type FakeSelfSubjectReviews struct { + Fake *FakeAuthenticationV1beta1 +} + +var selfsubjectreviewsResource = v1beta1.SchemeGroupVersion.WithResource("selfsubjectreviews") + +var selfsubjectreviewsKind = v1beta1.SchemeGroupVersion.WithKind("SelfSubjectReview") + +// Create takes the representation of a selfSubjectReview and creates it. Returns the server's representation of the selfSubjectReview, and an error, if there is any. +func (c *FakeSelfSubjectReviews) Create(ctx context.Context, selfSubjectReview *v1beta1.SelfSubjectReview, opts v1.CreateOptions) (result *v1beta1.SelfSubjectReview, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(selfsubjectreviewsResource, selfSubjectReview), &v1beta1.SelfSubjectReview{}) + if obj == nil { + return nil, err + } + return obj.(*v1beta1.SelfSubjectReview), err +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/fake/fake_tokenreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/fake/fake_tokenreview.go index 0da3ec6f43..b1988a67a3 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/fake/fake_tokenreview.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/fake/fake_tokenreview.go @@ -23,7 +23,6 @@ import ( v1beta1 "k8s.io/api/authentication/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - schema "k8s.io/apimachinery/pkg/runtime/schema" testing "k8s.io/client-go/testing" ) @@ -32,9 +31,9 @@ type FakeTokenReviews struct { Fake *FakeAuthenticationV1beta1 } -var tokenreviewsResource = schema.GroupVersionResource{Group: "authentication.k8s.io", Version: "v1beta1", Resource: "tokenreviews"} +var tokenreviewsResource = v1beta1.SchemeGroupVersion.WithResource("tokenreviews") -var tokenreviewsKind = schema.GroupVersionKind{Group: "authentication.k8s.io", Version: "v1beta1", Kind: "TokenReview"} +var tokenreviewsKind = v1beta1.SchemeGroupVersion.WithKind("TokenReview") // Create takes the representation of a tokenReview and creates it. Returns the server's representation of the tokenReview, and an error, if there is any. func (c *FakeTokenReviews) Create(ctx context.Context, tokenReview *v1beta1.TokenReview, opts v1.CreateOptions) (result *v1beta1.TokenReview, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/generated_expansion.go index 60bf15ab99..527a458d74 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/generated_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/generated_expansion.go @@ -18,4 +18,6 @@ limitations under the License. package v1beta1 +type SelfSubjectReviewExpansion interface{} + type TokenReviewExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/selfsubjectreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/selfsubjectreview.go new file mode 100644 index 0000000000..9d54826a31 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/selfsubjectreview.go @@ -0,0 +1,64 @@ +/* +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 ( + "context" + + v1beta1 "k8s.io/api/authentication/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// SelfSubjectReviewsGetter has a method to return a SelfSubjectReviewInterface. +// A group's client should implement this interface. +type SelfSubjectReviewsGetter interface { + SelfSubjectReviews() SelfSubjectReviewInterface +} + +// SelfSubjectReviewInterface has methods to work with SelfSubjectReview resources. +type SelfSubjectReviewInterface interface { + Create(ctx context.Context, selfSubjectReview *v1beta1.SelfSubjectReview, opts v1.CreateOptions) (*v1beta1.SelfSubjectReview, error) + SelfSubjectReviewExpansion +} + +// selfSubjectReviews implements SelfSubjectReviewInterface +type selfSubjectReviews struct { + client rest.Interface +} + +// newSelfSubjectReviews returns a SelfSubjectReviews +func newSelfSubjectReviews(c *AuthenticationV1beta1Client) *selfSubjectReviews { + return &selfSubjectReviews{ + client: c.RESTClient(), + } +} + +// Create takes the representation of a selfSubjectReview and creates it. Returns the server's representation of the selfSubjectReview, and an error, if there is any. +func (c *selfSubjectReviews) Create(ctx context.Context, selfSubjectReview *v1beta1.SelfSubjectReview, opts v1.CreateOptions) (result *v1beta1.SelfSubjectReview, err error) { + result = &v1beta1.SelfSubjectReview{} + err = c.client.Post(). + Resource("selfsubjectreviews"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(selfSubjectReview). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_localsubjectaccessreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_localsubjectaccessreview.go index d74ae0a474..43ea05328c 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_localsubjectaccessreview.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_localsubjectaccessreview.go @@ -23,7 +23,6 @@ import ( v1 "k8s.io/api/authorization/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - schema "k8s.io/apimachinery/pkg/runtime/schema" testing "k8s.io/client-go/testing" ) @@ -33,9 +32,9 @@ type FakeLocalSubjectAccessReviews struct { ns string } -var localsubjectaccessreviewsResource = schema.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1", Resource: "localsubjectaccessreviews"} +var localsubjectaccessreviewsResource = v1.SchemeGroupVersion.WithResource("localsubjectaccessreviews") -var localsubjectaccessreviewsKind = schema.GroupVersionKind{Group: "authorization.k8s.io", Version: "v1", Kind: "LocalSubjectAccessReview"} +var localsubjectaccessreviewsKind = v1.SchemeGroupVersion.WithKind("LocalSubjectAccessReview") // Create takes the representation of a localSubjectAccessReview and creates it. Returns the server's representation of the localSubjectAccessReview, and an error, if there is any. func (c *FakeLocalSubjectAccessReviews) Create(ctx context.Context, localSubjectAccessReview *v1.LocalSubjectAccessReview, opts metav1.CreateOptions) (result *v1.LocalSubjectAccessReview, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_selfsubjectaccessreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_selfsubjectaccessreview.go index 80ebbbd45f..27642266d6 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_selfsubjectaccessreview.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_selfsubjectaccessreview.go @@ -23,7 +23,6 @@ import ( v1 "k8s.io/api/authorization/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - schema "k8s.io/apimachinery/pkg/runtime/schema" testing "k8s.io/client-go/testing" ) @@ -32,9 +31,9 @@ type FakeSelfSubjectAccessReviews struct { Fake *FakeAuthorizationV1 } -var selfsubjectaccessreviewsResource = schema.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1", Resource: "selfsubjectaccessreviews"} +var selfsubjectaccessreviewsResource = v1.SchemeGroupVersion.WithResource("selfsubjectaccessreviews") -var selfsubjectaccessreviewsKind = schema.GroupVersionKind{Group: "authorization.k8s.io", Version: "v1", Kind: "SelfSubjectAccessReview"} +var selfsubjectaccessreviewsKind = v1.SchemeGroupVersion.WithKind("SelfSubjectAccessReview") // Create takes the representation of a selfSubjectAccessReview and creates it. Returns the server's representation of the selfSubjectAccessReview, and an error, if there is any. func (c *FakeSelfSubjectAccessReviews) Create(ctx context.Context, selfSubjectAccessReview *v1.SelfSubjectAccessReview, opts metav1.CreateOptions) (result *v1.SelfSubjectAccessReview, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_selfsubjectrulesreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_selfsubjectrulesreview.go index dd70908ad3..cd6c682d16 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_selfsubjectrulesreview.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_selfsubjectrulesreview.go @@ -23,7 +23,6 @@ import ( v1 "k8s.io/api/authorization/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - schema "k8s.io/apimachinery/pkg/runtime/schema" testing "k8s.io/client-go/testing" ) @@ -32,9 +31,9 @@ type FakeSelfSubjectRulesReviews struct { Fake *FakeAuthorizationV1 } -var selfsubjectrulesreviewsResource = schema.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1", Resource: "selfsubjectrulesreviews"} +var selfsubjectrulesreviewsResource = v1.SchemeGroupVersion.WithResource("selfsubjectrulesreviews") -var selfsubjectrulesreviewsKind = schema.GroupVersionKind{Group: "authorization.k8s.io", Version: "v1", Kind: "SelfSubjectRulesReview"} +var selfsubjectrulesreviewsKind = v1.SchemeGroupVersion.WithKind("SelfSubjectRulesReview") // Create takes the representation of a selfSubjectRulesReview and creates it. Returns the server's representation of the selfSubjectRulesReview, and an error, if there is any. func (c *FakeSelfSubjectRulesReviews) Create(ctx context.Context, selfSubjectRulesReview *v1.SelfSubjectRulesReview, opts metav1.CreateOptions) (result *v1.SelfSubjectRulesReview, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_subjectaccessreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_subjectaccessreview.go index b480b2b418..09dab64807 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_subjectaccessreview.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1/fake/fake_subjectaccessreview.go @@ -23,7 +23,6 @@ import ( v1 "k8s.io/api/authorization/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - schema "k8s.io/apimachinery/pkg/runtime/schema" testing "k8s.io/client-go/testing" ) @@ -32,9 +31,9 @@ type FakeSubjectAccessReviews struct { Fake *FakeAuthorizationV1 } -var subjectaccessreviewsResource = schema.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1", Resource: "subjectaccessreviews"} +var subjectaccessreviewsResource = v1.SchemeGroupVersion.WithResource("subjectaccessreviews") -var subjectaccessreviewsKind = schema.GroupVersionKind{Group: "authorization.k8s.io", Version: "v1", Kind: "SubjectAccessReview"} +var subjectaccessreviewsKind = v1.SchemeGroupVersion.WithKind("SubjectAccessReview") // Create takes the representation of a subjectAccessReview and creates it. Returns the server's representation of the subjectAccessReview, and an error, if there is any. func (c *FakeSubjectAccessReviews) Create(ctx context.Context, subjectAccessReview *v1.SubjectAccessReview, opts metav1.CreateOptions) (result *v1.SubjectAccessReview, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_localsubjectaccessreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_localsubjectaccessreview.go index 2d3ba44628..104e979d19 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_localsubjectaccessreview.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_localsubjectaccessreview.go @@ -23,7 +23,6 @@ import ( v1beta1 "k8s.io/api/authorization/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - schema "k8s.io/apimachinery/pkg/runtime/schema" testing "k8s.io/client-go/testing" ) @@ -33,9 +32,9 @@ type FakeLocalSubjectAccessReviews struct { ns string } -var localsubjectaccessreviewsResource = schema.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1beta1", Resource: "localsubjectaccessreviews"} +var localsubjectaccessreviewsResource = v1beta1.SchemeGroupVersion.WithResource("localsubjectaccessreviews") -var localsubjectaccessreviewsKind = schema.GroupVersionKind{Group: "authorization.k8s.io", Version: "v1beta1", Kind: "LocalSubjectAccessReview"} +var localsubjectaccessreviewsKind = v1beta1.SchemeGroupVersion.WithKind("LocalSubjectAccessReview") // Create takes the representation of a localSubjectAccessReview and creates it. Returns the server's representation of the localSubjectAccessReview, and an error, if there is any. func (c *FakeLocalSubjectAccessReviews) Create(ctx context.Context, localSubjectAccessReview *v1beta1.LocalSubjectAccessReview, opts v1.CreateOptions) (result *v1beta1.LocalSubjectAccessReview, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_selfsubjectaccessreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_selfsubjectaccessreview.go index febe90c77a..517e48b760 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_selfsubjectaccessreview.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_selfsubjectaccessreview.go @@ -23,7 +23,6 @@ import ( v1beta1 "k8s.io/api/authorization/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - schema "k8s.io/apimachinery/pkg/runtime/schema" testing "k8s.io/client-go/testing" ) @@ -32,9 +31,9 @@ type FakeSelfSubjectAccessReviews struct { Fake *FakeAuthorizationV1beta1 } -var selfsubjectaccessreviewsResource = schema.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1beta1", Resource: "selfsubjectaccessreviews"} +var selfsubjectaccessreviewsResource = v1beta1.SchemeGroupVersion.WithResource("selfsubjectaccessreviews") -var selfsubjectaccessreviewsKind = schema.GroupVersionKind{Group: "authorization.k8s.io", Version: "v1beta1", Kind: "SelfSubjectAccessReview"} +var selfsubjectaccessreviewsKind = v1beta1.SchemeGroupVersion.WithKind("SelfSubjectAccessReview") // Create takes the representation of a selfSubjectAccessReview and creates it. Returns the server's representation of the selfSubjectAccessReview, and an error, if there is any. func (c *FakeSelfSubjectAccessReviews) Create(ctx context.Context, selfSubjectAccessReview *v1beta1.SelfSubjectAccessReview, opts v1.CreateOptions) (result *v1beta1.SelfSubjectAccessReview, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_selfsubjectrulesreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_selfsubjectrulesreview.go index 02df06012a..3aed050fcf 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_selfsubjectrulesreview.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_selfsubjectrulesreview.go @@ -23,7 +23,6 @@ import ( v1beta1 "k8s.io/api/authorization/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - schema "k8s.io/apimachinery/pkg/runtime/schema" testing "k8s.io/client-go/testing" ) @@ -32,9 +31,9 @@ type FakeSelfSubjectRulesReviews struct { Fake *FakeAuthorizationV1beta1 } -var selfsubjectrulesreviewsResource = schema.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1beta1", Resource: "selfsubjectrulesreviews"} +var selfsubjectrulesreviewsResource = v1beta1.SchemeGroupVersion.WithResource("selfsubjectrulesreviews") -var selfsubjectrulesreviewsKind = schema.GroupVersionKind{Group: "authorization.k8s.io", Version: "v1beta1", Kind: "SelfSubjectRulesReview"} +var selfsubjectrulesreviewsKind = v1beta1.SchemeGroupVersion.WithKind("SelfSubjectRulesReview") // Create takes the representation of a selfSubjectRulesReview and creates it. Returns the server's representation of the selfSubjectRulesReview, and an error, if there is any. func (c *FakeSelfSubjectRulesReviews) Create(ctx context.Context, selfSubjectRulesReview *v1beta1.SelfSubjectRulesReview, opts v1.CreateOptions) (result *v1beta1.SelfSubjectRulesReview, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_subjectaccessreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_subjectaccessreview.go index b5be913c4b..e9bfa521a2 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_subjectaccessreview.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1/fake/fake_subjectaccessreview.go @@ -23,7 +23,6 @@ import ( v1beta1 "k8s.io/api/authorization/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - schema "k8s.io/apimachinery/pkg/runtime/schema" testing "k8s.io/client-go/testing" ) @@ -32,9 +31,9 @@ type FakeSubjectAccessReviews struct { Fake *FakeAuthorizationV1beta1 } -var subjectaccessreviewsResource = schema.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1beta1", Resource: "subjectaccessreviews"} +var subjectaccessreviewsResource = v1beta1.SchemeGroupVersion.WithResource("subjectaccessreviews") -var subjectaccessreviewsKind = schema.GroupVersionKind{Group: "authorization.k8s.io", Version: "v1beta1", Kind: "SubjectAccessReview"} +var subjectaccessreviewsKind = v1beta1.SchemeGroupVersion.WithKind("SubjectAccessReview") // Create takes the representation of a subjectAccessReview and creates it. Returns the server's representation of the subjectAccessReview, and an error, if there is any. func (c *FakeSubjectAccessReviews) Create(ctx context.Context, subjectAccessReview *v1beta1.SubjectAccessReview, opts v1.CreateOptions) (result *v1beta1.SubjectAccessReview, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v1/fake/fake_horizontalpodautoscaler.go b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v1/fake/fake_horizontalpodautoscaler.go index dcd47480ba..a2c95b7539 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v1/fake/fake_horizontalpodautoscaler.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v1/fake/fake_horizontalpodautoscaler.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - autoscalingv1 "k8s.io/api/autoscaling/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/autoscaling/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsautoscalingv1 "k8s.io/client-go/applyconfigurations/autoscaling/v1" + autoscalingv1 "k8s.io/client-go/applyconfigurations/autoscaling/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeHorizontalPodAutoscalers struct { ns string } -var horizontalpodautoscalersResource = schema.GroupVersionResource{Group: "autoscaling", Version: "v1", Resource: "horizontalpodautoscalers"} +var horizontalpodautoscalersResource = v1.SchemeGroupVersion.WithResource("horizontalpodautoscalers") -var horizontalpodautoscalersKind = schema.GroupVersionKind{Group: "autoscaling", Version: "v1", Kind: "HorizontalPodAutoscaler"} +var horizontalpodautoscalersKind = v1.SchemeGroupVersion.WithKind("HorizontalPodAutoscaler") // Get takes name of the horizontalPodAutoscaler, and returns the corresponding horizontalPodAutoscaler object, and an error if there is any. -func (c *FakeHorizontalPodAutoscalers) Get(ctx context.Context, name string, options v1.GetOptions) (result *autoscalingv1.HorizontalPodAutoscaler, err error) { +func (c *FakeHorizontalPodAutoscalers) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.HorizontalPodAutoscaler, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(horizontalpodautoscalersResource, c.ns, name), &autoscalingv1.HorizontalPodAutoscaler{}) + Invokes(testing.NewGetAction(horizontalpodautoscalersResource, c.ns, name), &v1.HorizontalPodAutoscaler{}) if obj == nil { return nil, err } - return obj.(*autoscalingv1.HorizontalPodAutoscaler), err + return obj.(*v1.HorizontalPodAutoscaler), err } // List takes label and field selectors, and returns the list of HorizontalPodAutoscalers that match those selectors. -func (c *FakeHorizontalPodAutoscalers) List(ctx context.Context, opts v1.ListOptions) (result *autoscalingv1.HorizontalPodAutoscalerList, err error) { +func (c *FakeHorizontalPodAutoscalers) List(ctx context.Context, opts metav1.ListOptions) (result *v1.HorizontalPodAutoscalerList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(horizontalpodautoscalersResource, horizontalpodautoscalersKind, c.ns, opts), &autoscalingv1.HorizontalPodAutoscalerList{}) + Invokes(testing.NewListAction(horizontalpodautoscalersResource, horizontalpodautoscalersKind, c.ns, opts), &v1.HorizontalPodAutoscalerList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeHorizontalPodAutoscalers) List(ctx context.Context, opts v1.ListOpt if label == nil { label = labels.Everything() } - list := &autoscalingv1.HorizontalPodAutoscalerList{ListMeta: obj.(*autoscalingv1.HorizontalPodAutoscalerList).ListMeta} - for _, item := range obj.(*autoscalingv1.HorizontalPodAutoscalerList).Items { + list := &v1.HorizontalPodAutoscalerList{ListMeta: obj.(*v1.HorizontalPodAutoscalerList).ListMeta} + for _, item := range obj.(*v1.HorizontalPodAutoscalerList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,75 +76,75 @@ func (c *FakeHorizontalPodAutoscalers) List(ctx context.Context, opts v1.ListOpt } // Watch returns a watch.Interface that watches the requested horizontalPodAutoscalers. -func (c *FakeHorizontalPodAutoscalers) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeHorizontalPodAutoscalers) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(horizontalpodautoscalersResource, c.ns, opts)) } // Create takes the representation of a horizontalPodAutoscaler and creates it. Returns the server's representation of the horizontalPodAutoscaler, and an error, if there is any. -func (c *FakeHorizontalPodAutoscalers) Create(ctx context.Context, horizontalPodAutoscaler *autoscalingv1.HorizontalPodAutoscaler, opts v1.CreateOptions) (result *autoscalingv1.HorizontalPodAutoscaler, err error) { +func (c *FakeHorizontalPodAutoscalers) Create(ctx context.Context, horizontalPodAutoscaler *v1.HorizontalPodAutoscaler, opts metav1.CreateOptions) (result *v1.HorizontalPodAutoscaler, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(horizontalpodautoscalersResource, c.ns, horizontalPodAutoscaler), &autoscalingv1.HorizontalPodAutoscaler{}) + Invokes(testing.NewCreateAction(horizontalpodautoscalersResource, c.ns, horizontalPodAutoscaler), &v1.HorizontalPodAutoscaler{}) if obj == nil { return nil, err } - return obj.(*autoscalingv1.HorizontalPodAutoscaler), err + return obj.(*v1.HorizontalPodAutoscaler), err } // Update takes the representation of a horizontalPodAutoscaler and updates it. Returns the server's representation of the horizontalPodAutoscaler, and an error, if there is any. -func (c *FakeHorizontalPodAutoscalers) Update(ctx context.Context, horizontalPodAutoscaler *autoscalingv1.HorizontalPodAutoscaler, opts v1.UpdateOptions) (result *autoscalingv1.HorizontalPodAutoscaler, err error) { +func (c *FakeHorizontalPodAutoscalers) Update(ctx context.Context, horizontalPodAutoscaler *v1.HorizontalPodAutoscaler, opts metav1.UpdateOptions) (result *v1.HorizontalPodAutoscaler, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(horizontalpodautoscalersResource, c.ns, horizontalPodAutoscaler), &autoscalingv1.HorizontalPodAutoscaler{}) + Invokes(testing.NewUpdateAction(horizontalpodautoscalersResource, c.ns, horizontalPodAutoscaler), &v1.HorizontalPodAutoscaler{}) if obj == nil { return nil, err } - return obj.(*autoscalingv1.HorizontalPodAutoscaler), err + return obj.(*v1.HorizontalPodAutoscaler), 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 *FakeHorizontalPodAutoscalers) UpdateStatus(ctx context.Context, horizontalPodAutoscaler *autoscalingv1.HorizontalPodAutoscaler, opts v1.UpdateOptions) (*autoscalingv1.HorizontalPodAutoscaler, error) { +func (c *FakeHorizontalPodAutoscalers) UpdateStatus(ctx context.Context, horizontalPodAutoscaler *v1.HorizontalPodAutoscaler, opts metav1.UpdateOptions) (*v1.HorizontalPodAutoscaler, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(horizontalpodautoscalersResource, "status", c.ns, horizontalPodAutoscaler), &autoscalingv1.HorizontalPodAutoscaler{}) + Invokes(testing.NewUpdateSubresourceAction(horizontalpodautoscalersResource, "status", c.ns, horizontalPodAutoscaler), &v1.HorizontalPodAutoscaler{}) if obj == nil { return nil, err } - return obj.(*autoscalingv1.HorizontalPodAutoscaler), err + return obj.(*v1.HorizontalPodAutoscaler), err } // Delete takes name of the horizontalPodAutoscaler and deletes it. Returns an error if one occurs. -func (c *FakeHorizontalPodAutoscalers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeHorizontalPodAutoscalers) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(horizontalpodautoscalersResource, c.ns, name, opts), &autoscalingv1.HorizontalPodAutoscaler{}) + Invokes(testing.NewDeleteActionWithOptions(horizontalpodautoscalersResource, c.ns, name, opts), &v1.HorizontalPodAutoscaler{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeHorizontalPodAutoscalers) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeHorizontalPodAutoscalers) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(horizontalpodautoscalersResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &autoscalingv1.HorizontalPodAutoscalerList{}) + _, err := c.Fake.Invokes(action, &v1.HorizontalPodAutoscalerList{}) return err } // Patch applies the patch and returns the patched horizontalPodAutoscaler. -func (c *FakeHorizontalPodAutoscalers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *autoscalingv1.HorizontalPodAutoscaler, err error) { +func (c *FakeHorizontalPodAutoscalers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.HorizontalPodAutoscaler, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(horizontalpodautoscalersResource, c.ns, name, pt, data, subresources...), &autoscalingv1.HorizontalPodAutoscaler{}) + Invokes(testing.NewPatchSubresourceAction(horizontalpodautoscalersResource, c.ns, name, pt, data, subresources...), &v1.HorizontalPodAutoscaler{}) if obj == nil { return nil, err } - return obj.(*autoscalingv1.HorizontalPodAutoscaler), err + return obj.(*v1.HorizontalPodAutoscaler), err } // Apply takes the given apply declarative configuration, applies it and returns the applied horizontalPodAutoscaler. -func (c *FakeHorizontalPodAutoscalers) Apply(ctx context.Context, horizontalPodAutoscaler *applyconfigurationsautoscalingv1.HorizontalPodAutoscalerApplyConfiguration, opts v1.ApplyOptions) (result *autoscalingv1.HorizontalPodAutoscaler, err error) { +func (c *FakeHorizontalPodAutoscalers) Apply(ctx context.Context, horizontalPodAutoscaler *autoscalingv1.HorizontalPodAutoscalerApplyConfiguration, opts metav1.ApplyOptions) (result *v1.HorizontalPodAutoscaler, err error) { if horizontalPodAutoscaler == nil { return nil, fmt.Errorf("horizontalPodAutoscaler provided to Apply must not be nil") } @@ -158,17 +157,17 @@ func (c *FakeHorizontalPodAutoscalers) Apply(ctx context.Context, horizontalPodA return nil, fmt.Errorf("horizontalPodAutoscaler.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(horizontalpodautoscalersResource, c.ns, *name, types.ApplyPatchType, data), &autoscalingv1.HorizontalPodAutoscaler{}) + Invokes(testing.NewPatchSubresourceAction(horizontalpodautoscalersResource, c.ns, *name, types.ApplyPatchType, data), &v1.HorizontalPodAutoscaler{}) if obj == nil { return nil, err } - return obj.(*autoscalingv1.HorizontalPodAutoscaler), err + return obj.(*v1.HorizontalPodAutoscaler), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeHorizontalPodAutoscalers) ApplyStatus(ctx context.Context, horizontalPodAutoscaler *applyconfigurationsautoscalingv1.HorizontalPodAutoscalerApplyConfiguration, opts v1.ApplyOptions) (result *autoscalingv1.HorizontalPodAutoscaler, err error) { +func (c *FakeHorizontalPodAutoscalers) ApplyStatus(ctx context.Context, horizontalPodAutoscaler *autoscalingv1.HorizontalPodAutoscalerApplyConfiguration, opts metav1.ApplyOptions) (result *v1.HorizontalPodAutoscaler, err error) { if horizontalPodAutoscaler == nil { return nil, fmt.Errorf("horizontalPodAutoscaler provided to Apply must not be nil") } @@ -181,10 +180,10 @@ func (c *FakeHorizontalPodAutoscalers) ApplyStatus(ctx context.Context, horizont return nil, fmt.Errorf("horizontalPodAutoscaler.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(horizontalpodautoscalersResource, c.ns, *name, types.ApplyPatchType, data, "status"), &autoscalingv1.HorizontalPodAutoscaler{}) + Invokes(testing.NewPatchSubresourceAction(horizontalpodautoscalersResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.HorizontalPodAutoscaler{}) if obj == nil { return nil, err } - return obj.(*autoscalingv1.HorizontalPodAutoscaler), err + return obj.(*v1.HorizontalPodAutoscaler), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2/fake/fake_horizontalpodautoscaler.go b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2/fake/fake_horizontalpodautoscaler.go index ca4b24704d..cfcc208232 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2/fake/fake_horizontalpodautoscaler.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2/fake/fake_horizontalpodautoscaler.go @@ -26,7 +26,6 @@ import ( v2 "k8s.io/api/autoscaling/v2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" autoscalingv2 "k8s.io/client-go/applyconfigurations/autoscaling/v2" @@ -39,9 +38,9 @@ type FakeHorizontalPodAutoscalers struct { ns string } -var horizontalpodautoscalersResource = schema.GroupVersionResource{Group: "autoscaling", Version: "v2", Resource: "horizontalpodautoscalers"} +var horizontalpodautoscalersResource = v2.SchemeGroupVersion.WithResource("horizontalpodautoscalers") -var horizontalpodautoscalersKind = schema.GroupVersionKind{Group: "autoscaling", Version: "v2", Kind: "HorizontalPodAutoscaler"} +var horizontalpodautoscalersKind = v2.SchemeGroupVersion.WithKind("HorizontalPodAutoscaler") // Get takes name of the horizontalPodAutoscaler, and returns the corresponding horizontalPodAutoscaler object, and an error if there is any. func (c *FakeHorizontalPodAutoscalers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v2.HorizontalPodAutoscaler, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake/fake_horizontalpodautoscaler.go b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake/fake_horizontalpodautoscaler.go index 2a750abddf..0b2658e642 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake/fake_horizontalpodautoscaler.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1/fake/fake_horizontalpodautoscaler.go @@ -26,7 +26,6 @@ import ( v2beta1 "k8s.io/api/autoscaling/v2beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" autoscalingv2beta1 "k8s.io/client-go/applyconfigurations/autoscaling/v2beta1" @@ -39,9 +38,9 @@ type FakeHorizontalPodAutoscalers struct { ns string } -var horizontalpodautoscalersResource = schema.GroupVersionResource{Group: "autoscaling", Version: "v2beta1", Resource: "horizontalpodautoscalers"} +var horizontalpodautoscalersResource = v2beta1.SchemeGroupVersion.WithResource("horizontalpodautoscalers") -var horizontalpodautoscalersKind = schema.GroupVersionKind{Group: "autoscaling", Version: "v2beta1", Kind: "HorizontalPodAutoscaler"} +var horizontalpodautoscalersKind = v2beta1.SchemeGroupVersion.WithKind("HorizontalPodAutoscaler") // Get takes name of the horizontalPodAutoscaler, and returns the corresponding horizontalPodAutoscaler object, and an error if there is any. func (c *FakeHorizontalPodAutoscalers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v2beta1.HorizontalPodAutoscaler, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake/fake_horizontalpodautoscaler.go b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake/fake_horizontalpodautoscaler.go index 00d642d856..0a7c93c3d3 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake/fake_horizontalpodautoscaler.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2/fake/fake_horizontalpodautoscaler.go @@ -26,7 +26,6 @@ import ( v2beta2 "k8s.io/api/autoscaling/v2beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" autoscalingv2beta2 "k8s.io/client-go/applyconfigurations/autoscaling/v2beta2" @@ -39,9 +38,9 @@ type FakeHorizontalPodAutoscalers struct { ns string } -var horizontalpodautoscalersResource = schema.GroupVersionResource{Group: "autoscaling", Version: "v2beta2", Resource: "horizontalpodautoscalers"} +var horizontalpodautoscalersResource = v2beta2.SchemeGroupVersion.WithResource("horizontalpodautoscalers") -var horizontalpodautoscalersKind = schema.GroupVersionKind{Group: "autoscaling", Version: "v2beta2", Kind: "HorizontalPodAutoscaler"} +var horizontalpodautoscalersKind = v2beta2.SchemeGroupVersion.WithKind("HorizontalPodAutoscaler") // Get takes name of the horizontalPodAutoscaler, and returns the corresponding horizontalPodAutoscaler object, and an error if there is any. func (c *FakeHorizontalPodAutoscalers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v2beta2.HorizontalPodAutoscaler, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/batch/v1/fake/fake_cronjob.go b/vendor/k8s.io/client-go/kubernetes/typed/batch/v1/fake/fake_cronjob.go index 39f4ca0232..0cbcce6d81 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/batch/v1/fake/fake_cronjob.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/batch/v1/fake/fake_cronjob.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - batchv1 "k8s.io/api/batch/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/batch/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsbatchv1 "k8s.io/client-go/applyconfigurations/batch/v1" + batchv1 "k8s.io/client-go/applyconfigurations/batch/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeCronJobs struct { ns string } -var cronjobsResource = schema.GroupVersionResource{Group: "batch", Version: "v1", Resource: "cronjobs"} +var cronjobsResource = v1.SchemeGroupVersion.WithResource("cronjobs") -var cronjobsKind = schema.GroupVersionKind{Group: "batch", Version: "v1", Kind: "CronJob"} +var cronjobsKind = v1.SchemeGroupVersion.WithKind("CronJob") // Get takes name of the cronJob, and returns the corresponding cronJob object, and an error if there is any. -func (c *FakeCronJobs) Get(ctx context.Context, name string, options v1.GetOptions) (result *batchv1.CronJob, err error) { +func (c *FakeCronJobs) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CronJob, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(cronjobsResource, c.ns, name), &batchv1.CronJob{}) + Invokes(testing.NewGetAction(cronjobsResource, c.ns, name), &v1.CronJob{}) if obj == nil { return nil, err } - return obj.(*batchv1.CronJob), err + return obj.(*v1.CronJob), err } // List takes label and field selectors, and returns the list of CronJobs that match those selectors. -func (c *FakeCronJobs) List(ctx context.Context, opts v1.ListOptions) (result *batchv1.CronJobList, err error) { +func (c *FakeCronJobs) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CronJobList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(cronjobsResource, cronjobsKind, c.ns, opts), &batchv1.CronJobList{}) + Invokes(testing.NewListAction(cronjobsResource, cronjobsKind, c.ns, opts), &v1.CronJobList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeCronJobs) List(ctx context.Context, opts v1.ListOptions) (result *b if label == nil { label = labels.Everything() } - list := &batchv1.CronJobList{ListMeta: obj.(*batchv1.CronJobList).ListMeta} - for _, item := range obj.(*batchv1.CronJobList).Items { + list := &v1.CronJobList{ListMeta: obj.(*v1.CronJobList).ListMeta} + for _, item := range obj.(*v1.CronJobList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,75 +76,75 @@ func (c *FakeCronJobs) List(ctx context.Context, opts v1.ListOptions) (result *b } // Watch returns a watch.Interface that watches the requested cronJobs. -func (c *FakeCronJobs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeCronJobs) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(cronjobsResource, c.ns, opts)) } // Create takes the representation of a cronJob and creates it. Returns the server's representation of the cronJob, and an error, if there is any. -func (c *FakeCronJobs) Create(ctx context.Context, cronJob *batchv1.CronJob, opts v1.CreateOptions) (result *batchv1.CronJob, err error) { +func (c *FakeCronJobs) Create(ctx context.Context, cronJob *v1.CronJob, opts metav1.CreateOptions) (result *v1.CronJob, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(cronjobsResource, c.ns, cronJob), &batchv1.CronJob{}) + Invokes(testing.NewCreateAction(cronjobsResource, c.ns, cronJob), &v1.CronJob{}) if obj == nil { return nil, err } - return obj.(*batchv1.CronJob), err + return obj.(*v1.CronJob), err } // Update takes the representation of a cronJob and updates it. Returns the server's representation of the cronJob, and an error, if there is any. -func (c *FakeCronJobs) Update(ctx context.Context, cronJob *batchv1.CronJob, opts v1.UpdateOptions) (result *batchv1.CronJob, err error) { +func (c *FakeCronJobs) Update(ctx context.Context, cronJob *v1.CronJob, opts metav1.UpdateOptions) (result *v1.CronJob, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(cronjobsResource, c.ns, cronJob), &batchv1.CronJob{}) + Invokes(testing.NewUpdateAction(cronjobsResource, c.ns, cronJob), &v1.CronJob{}) if obj == nil { return nil, err } - return obj.(*batchv1.CronJob), err + return obj.(*v1.CronJob), 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 *FakeCronJobs) UpdateStatus(ctx context.Context, cronJob *batchv1.CronJob, opts v1.UpdateOptions) (*batchv1.CronJob, error) { +func (c *FakeCronJobs) UpdateStatus(ctx context.Context, cronJob *v1.CronJob, opts metav1.UpdateOptions) (*v1.CronJob, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(cronjobsResource, "status", c.ns, cronJob), &batchv1.CronJob{}) + Invokes(testing.NewUpdateSubresourceAction(cronjobsResource, "status", c.ns, cronJob), &v1.CronJob{}) if obj == nil { return nil, err } - return obj.(*batchv1.CronJob), err + return obj.(*v1.CronJob), err } // Delete takes name of the cronJob and deletes it. Returns an error if one occurs. -func (c *FakeCronJobs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeCronJobs) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(cronjobsResource, c.ns, name, opts), &batchv1.CronJob{}) + Invokes(testing.NewDeleteActionWithOptions(cronjobsResource, c.ns, name, opts), &v1.CronJob{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeCronJobs) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeCronJobs) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(cronjobsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &batchv1.CronJobList{}) + _, err := c.Fake.Invokes(action, &v1.CronJobList{}) return err } // Patch applies the patch and returns the patched cronJob. -func (c *FakeCronJobs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *batchv1.CronJob, err error) { +func (c *FakeCronJobs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CronJob, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(cronjobsResource, c.ns, name, pt, data, subresources...), &batchv1.CronJob{}) + Invokes(testing.NewPatchSubresourceAction(cronjobsResource, c.ns, name, pt, data, subresources...), &v1.CronJob{}) if obj == nil { return nil, err } - return obj.(*batchv1.CronJob), err + return obj.(*v1.CronJob), err } // Apply takes the given apply declarative configuration, applies it and returns the applied cronJob. -func (c *FakeCronJobs) Apply(ctx context.Context, cronJob *applyconfigurationsbatchv1.CronJobApplyConfiguration, opts v1.ApplyOptions) (result *batchv1.CronJob, err error) { +func (c *FakeCronJobs) Apply(ctx context.Context, cronJob *batchv1.CronJobApplyConfiguration, opts metav1.ApplyOptions) (result *v1.CronJob, err error) { if cronJob == nil { return nil, fmt.Errorf("cronJob provided to Apply must not be nil") } @@ -158,17 +157,17 @@ func (c *FakeCronJobs) Apply(ctx context.Context, cronJob *applyconfigurationsba return nil, fmt.Errorf("cronJob.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(cronjobsResource, c.ns, *name, types.ApplyPatchType, data), &batchv1.CronJob{}) + Invokes(testing.NewPatchSubresourceAction(cronjobsResource, c.ns, *name, types.ApplyPatchType, data), &v1.CronJob{}) if obj == nil { return nil, err } - return obj.(*batchv1.CronJob), err + return obj.(*v1.CronJob), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeCronJobs) ApplyStatus(ctx context.Context, cronJob *applyconfigurationsbatchv1.CronJobApplyConfiguration, opts v1.ApplyOptions) (result *batchv1.CronJob, err error) { +func (c *FakeCronJobs) ApplyStatus(ctx context.Context, cronJob *batchv1.CronJobApplyConfiguration, opts metav1.ApplyOptions) (result *v1.CronJob, err error) { if cronJob == nil { return nil, fmt.Errorf("cronJob provided to Apply must not be nil") } @@ -181,10 +180,10 @@ func (c *FakeCronJobs) ApplyStatus(ctx context.Context, cronJob *applyconfigurat return nil, fmt.Errorf("cronJob.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(cronjobsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &batchv1.CronJob{}) + Invokes(testing.NewPatchSubresourceAction(cronjobsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.CronJob{}) if obj == nil { return nil, err } - return obj.(*batchv1.CronJob), err + return obj.(*v1.CronJob), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/batch/v1/fake/fake_job.go b/vendor/k8s.io/client-go/kubernetes/typed/batch/v1/fake/fake_job.go index c44cddb3c0..cf1a913bdf 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/batch/v1/fake/fake_job.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/batch/v1/fake/fake_job.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - batchv1 "k8s.io/api/batch/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/batch/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsbatchv1 "k8s.io/client-go/applyconfigurations/batch/v1" + batchv1 "k8s.io/client-go/applyconfigurations/batch/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeJobs struct { ns string } -var jobsResource = schema.GroupVersionResource{Group: "batch", Version: "v1", Resource: "jobs"} +var jobsResource = v1.SchemeGroupVersion.WithResource("jobs") -var jobsKind = schema.GroupVersionKind{Group: "batch", Version: "v1", Kind: "Job"} +var jobsKind = v1.SchemeGroupVersion.WithKind("Job") // Get takes name of the job, and returns the corresponding job object, and an error if there is any. -func (c *FakeJobs) Get(ctx context.Context, name string, options v1.GetOptions) (result *batchv1.Job, err error) { +func (c *FakeJobs) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Job, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(jobsResource, c.ns, name), &batchv1.Job{}) + Invokes(testing.NewGetAction(jobsResource, c.ns, name), &v1.Job{}) if obj == nil { return nil, err } - return obj.(*batchv1.Job), err + return obj.(*v1.Job), err } // List takes label and field selectors, and returns the list of Jobs that match those selectors. -func (c *FakeJobs) List(ctx context.Context, opts v1.ListOptions) (result *batchv1.JobList, err error) { +func (c *FakeJobs) List(ctx context.Context, opts metav1.ListOptions) (result *v1.JobList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(jobsResource, jobsKind, c.ns, opts), &batchv1.JobList{}) + Invokes(testing.NewListAction(jobsResource, jobsKind, c.ns, opts), &v1.JobList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeJobs) List(ctx context.Context, opts v1.ListOptions) (result *batch if label == nil { label = labels.Everything() } - list := &batchv1.JobList{ListMeta: obj.(*batchv1.JobList).ListMeta} - for _, item := range obj.(*batchv1.JobList).Items { + list := &v1.JobList{ListMeta: obj.(*v1.JobList).ListMeta} + for _, item := range obj.(*v1.JobList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,75 +76,75 @@ func (c *FakeJobs) List(ctx context.Context, opts v1.ListOptions) (result *batch } // Watch returns a watch.Interface that watches the requested jobs. -func (c *FakeJobs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeJobs) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(jobsResource, c.ns, opts)) } // Create takes the representation of a job and creates it. Returns the server's representation of the job, and an error, if there is any. -func (c *FakeJobs) Create(ctx context.Context, job *batchv1.Job, opts v1.CreateOptions) (result *batchv1.Job, err error) { +func (c *FakeJobs) Create(ctx context.Context, job *v1.Job, opts metav1.CreateOptions) (result *v1.Job, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(jobsResource, c.ns, job), &batchv1.Job{}) + Invokes(testing.NewCreateAction(jobsResource, c.ns, job), &v1.Job{}) if obj == nil { return nil, err } - return obj.(*batchv1.Job), err + return obj.(*v1.Job), err } // Update takes the representation of a job and updates it. Returns the server's representation of the job, and an error, if there is any. -func (c *FakeJobs) Update(ctx context.Context, job *batchv1.Job, opts v1.UpdateOptions) (result *batchv1.Job, err error) { +func (c *FakeJobs) Update(ctx context.Context, job *v1.Job, opts metav1.UpdateOptions) (result *v1.Job, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(jobsResource, c.ns, job), &batchv1.Job{}) + Invokes(testing.NewUpdateAction(jobsResource, c.ns, job), &v1.Job{}) if obj == nil { return nil, err } - return obj.(*batchv1.Job), err + return obj.(*v1.Job), 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 *FakeJobs) UpdateStatus(ctx context.Context, job *batchv1.Job, opts v1.UpdateOptions) (*batchv1.Job, error) { +func (c *FakeJobs) UpdateStatus(ctx context.Context, job *v1.Job, opts metav1.UpdateOptions) (*v1.Job, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(jobsResource, "status", c.ns, job), &batchv1.Job{}) + Invokes(testing.NewUpdateSubresourceAction(jobsResource, "status", c.ns, job), &v1.Job{}) if obj == nil { return nil, err } - return obj.(*batchv1.Job), err + return obj.(*v1.Job), err } // Delete takes name of the job and deletes it. Returns an error if one occurs. -func (c *FakeJobs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeJobs) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(jobsResource, c.ns, name, opts), &batchv1.Job{}) + Invokes(testing.NewDeleteActionWithOptions(jobsResource, c.ns, name, opts), &v1.Job{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeJobs) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeJobs) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(jobsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &batchv1.JobList{}) + _, err := c.Fake.Invokes(action, &v1.JobList{}) return err } // Patch applies the patch and returns the patched job. -func (c *FakeJobs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *batchv1.Job, err error) { +func (c *FakeJobs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Job, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(jobsResource, c.ns, name, pt, data, subresources...), &batchv1.Job{}) + Invokes(testing.NewPatchSubresourceAction(jobsResource, c.ns, name, pt, data, subresources...), &v1.Job{}) if obj == nil { return nil, err } - return obj.(*batchv1.Job), err + return obj.(*v1.Job), err } // Apply takes the given apply declarative configuration, applies it and returns the applied job. -func (c *FakeJobs) Apply(ctx context.Context, job *applyconfigurationsbatchv1.JobApplyConfiguration, opts v1.ApplyOptions) (result *batchv1.Job, err error) { +func (c *FakeJobs) Apply(ctx context.Context, job *batchv1.JobApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Job, err error) { if job == nil { return nil, fmt.Errorf("job provided to Apply must not be nil") } @@ -158,17 +157,17 @@ func (c *FakeJobs) Apply(ctx context.Context, job *applyconfigurationsbatchv1.Jo return nil, fmt.Errorf("job.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(jobsResource, c.ns, *name, types.ApplyPatchType, data), &batchv1.Job{}) + Invokes(testing.NewPatchSubresourceAction(jobsResource, c.ns, *name, types.ApplyPatchType, data), &v1.Job{}) if obj == nil { return nil, err } - return obj.(*batchv1.Job), err + return obj.(*v1.Job), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeJobs) ApplyStatus(ctx context.Context, job *applyconfigurationsbatchv1.JobApplyConfiguration, opts v1.ApplyOptions) (result *batchv1.Job, err error) { +func (c *FakeJobs) ApplyStatus(ctx context.Context, job *batchv1.JobApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Job, err error) { if job == nil { return nil, fmt.Errorf("job provided to Apply must not be nil") } @@ -181,10 +180,10 @@ func (c *FakeJobs) ApplyStatus(ctx context.Context, job *applyconfigurationsbatc return nil, fmt.Errorf("job.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(jobsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &batchv1.Job{}) + Invokes(testing.NewPatchSubresourceAction(jobsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.Job{}) if obj == nil { return nil, err } - return obj.(*batchv1.Job), err + return obj.(*v1.Job), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/batch/v1beta1/fake/fake_cronjob.go b/vendor/k8s.io/client-go/kubernetes/typed/batch/v1beta1/fake/fake_cronjob.go index a8bad764f5..9d078f55a9 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/batch/v1beta1/fake/fake_cronjob.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/batch/v1beta1/fake/fake_cronjob.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/batch/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" batchv1beta1 "k8s.io/client-go/applyconfigurations/batch/v1beta1" @@ -39,9 +38,9 @@ type FakeCronJobs struct { ns string } -var cronjobsResource = schema.GroupVersionResource{Group: "batch", Version: "v1beta1", Resource: "cronjobs"} +var cronjobsResource = v1beta1.SchemeGroupVersion.WithResource("cronjobs") -var cronjobsKind = schema.GroupVersionKind{Group: "batch", Version: "v1beta1", Kind: "CronJob"} +var cronjobsKind = v1beta1.SchemeGroupVersion.WithKind("CronJob") // Get takes name of the cronJob, and returns the corresponding cronJob object, and an error if there is any. func (c *FakeCronJobs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.CronJob, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1/fake/fake_certificatesigningrequest.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1/fake/fake_certificatesigningrequest.go index 90a1e6dc66..adb7db0bf6 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1/fake/fake_certificatesigningrequest.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1/fake/fake_certificatesigningrequest.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - certificatesv1 "k8s.io/api/certificates/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/certificates/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscertificatesv1 "k8s.io/client-go/applyconfigurations/certificates/v1" + certificatesv1 "k8s.io/client-go/applyconfigurations/certificates/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakeCertificateSigningRequests struct { Fake *FakeCertificatesV1 } -var certificatesigningrequestsResource = schema.GroupVersionResource{Group: "certificates.k8s.io", Version: "v1", Resource: "certificatesigningrequests"} +var certificatesigningrequestsResource = v1.SchemeGroupVersion.WithResource("certificatesigningrequests") -var certificatesigningrequestsKind = schema.GroupVersionKind{Group: "certificates.k8s.io", Version: "v1", Kind: "CertificateSigningRequest"} +var certificatesigningrequestsKind = v1.SchemeGroupVersion.WithKind("CertificateSigningRequest") // Get takes name of the certificateSigningRequest, and returns the corresponding certificateSigningRequest object, and an error if there is any. -func (c *FakeCertificateSigningRequests) Get(ctx context.Context, name string, options v1.GetOptions) (result *certificatesv1.CertificateSigningRequest, err error) { +func (c *FakeCertificateSigningRequests) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CertificateSigningRequest, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(certificatesigningrequestsResource, name), &certificatesv1.CertificateSigningRequest{}) + Invokes(testing.NewRootGetAction(certificatesigningrequestsResource, name), &v1.CertificateSigningRequest{}) if obj == nil { return nil, err } - return obj.(*certificatesv1.CertificateSigningRequest), err + return obj.(*v1.CertificateSigningRequest), err } // List takes label and field selectors, and returns the list of CertificateSigningRequests that match those selectors. -func (c *FakeCertificateSigningRequests) List(ctx context.Context, opts v1.ListOptions) (result *certificatesv1.CertificateSigningRequestList, err error) { +func (c *FakeCertificateSigningRequests) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CertificateSigningRequestList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(certificatesigningrequestsResource, certificatesigningrequestsKind, opts), &certificatesv1.CertificateSigningRequestList{}) + Invokes(testing.NewRootListAction(certificatesigningrequestsResource, certificatesigningrequestsKind, opts), &v1.CertificateSigningRequestList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakeCertificateSigningRequests) List(ctx context.Context, opts v1.ListO if label == nil { label = labels.Everything() } - list := &certificatesv1.CertificateSigningRequestList{ListMeta: obj.(*certificatesv1.CertificateSigningRequestList).ListMeta} - for _, item := range obj.(*certificatesv1.CertificateSigningRequestList).Items { + list := &v1.CertificateSigningRequestList{ListMeta: obj.(*v1.CertificateSigningRequestList).ListMeta} + for _, item := range obj.(*v1.CertificateSigningRequestList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,69 +73,69 @@ func (c *FakeCertificateSigningRequests) List(ctx context.Context, opts v1.ListO } // Watch returns a watch.Interface that watches the requested certificateSigningRequests. -func (c *FakeCertificateSigningRequests) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeCertificateSigningRequests) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(certificatesigningrequestsResource, opts)) } // Create takes the representation of a certificateSigningRequest and creates it. Returns the server's representation of the certificateSigningRequest, and an error, if there is any. -func (c *FakeCertificateSigningRequests) Create(ctx context.Context, certificateSigningRequest *certificatesv1.CertificateSigningRequest, opts v1.CreateOptions) (result *certificatesv1.CertificateSigningRequest, err error) { +func (c *FakeCertificateSigningRequests) Create(ctx context.Context, certificateSigningRequest *v1.CertificateSigningRequest, opts metav1.CreateOptions) (result *v1.CertificateSigningRequest, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(certificatesigningrequestsResource, certificateSigningRequest), &certificatesv1.CertificateSigningRequest{}) + Invokes(testing.NewRootCreateAction(certificatesigningrequestsResource, certificateSigningRequest), &v1.CertificateSigningRequest{}) if obj == nil { return nil, err } - return obj.(*certificatesv1.CertificateSigningRequest), err + return obj.(*v1.CertificateSigningRequest), err } // Update takes the representation of a certificateSigningRequest and updates it. Returns the server's representation of the certificateSigningRequest, and an error, if there is any. -func (c *FakeCertificateSigningRequests) Update(ctx context.Context, certificateSigningRequest *certificatesv1.CertificateSigningRequest, opts v1.UpdateOptions) (result *certificatesv1.CertificateSigningRequest, err error) { +func (c *FakeCertificateSigningRequests) Update(ctx context.Context, certificateSigningRequest *v1.CertificateSigningRequest, opts metav1.UpdateOptions) (result *v1.CertificateSigningRequest, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(certificatesigningrequestsResource, certificateSigningRequest), &certificatesv1.CertificateSigningRequest{}) + Invokes(testing.NewRootUpdateAction(certificatesigningrequestsResource, certificateSigningRequest), &v1.CertificateSigningRequest{}) if obj == nil { return nil, err } - return obj.(*certificatesv1.CertificateSigningRequest), err + return obj.(*v1.CertificateSigningRequest), 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 *FakeCertificateSigningRequests) UpdateStatus(ctx context.Context, certificateSigningRequest *certificatesv1.CertificateSigningRequest, opts v1.UpdateOptions) (*certificatesv1.CertificateSigningRequest, error) { +func (c *FakeCertificateSigningRequests) UpdateStatus(ctx context.Context, certificateSigningRequest *v1.CertificateSigningRequest, opts metav1.UpdateOptions) (*v1.CertificateSigningRequest, error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateSubresourceAction(certificatesigningrequestsResource, "status", certificateSigningRequest), &certificatesv1.CertificateSigningRequest{}) + Invokes(testing.NewRootUpdateSubresourceAction(certificatesigningrequestsResource, "status", certificateSigningRequest), &v1.CertificateSigningRequest{}) if obj == nil { return nil, err } - return obj.(*certificatesv1.CertificateSigningRequest), err + return obj.(*v1.CertificateSigningRequest), err } // Delete takes name of the certificateSigningRequest and deletes it. Returns an error if one occurs. -func (c *FakeCertificateSigningRequests) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeCertificateSigningRequests) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(certificatesigningrequestsResource, name, opts), &certificatesv1.CertificateSigningRequest{}) + Invokes(testing.NewRootDeleteActionWithOptions(certificatesigningrequestsResource, name, opts), &v1.CertificateSigningRequest{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeCertificateSigningRequests) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeCertificateSigningRequests) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(certificatesigningrequestsResource, listOpts) - _, err := c.Fake.Invokes(action, &certificatesv1.CertificateSigningRequestList{}) + _, err := c.Fake.Invokes(action, &v1.CertificateSigningRequestList{}) return err } // Patch applies the patch and returns the patched certificateSigningRequest. -func (c *FakeCertificateSigningRequests) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *certificatesv1.CertificateSigningRequest, err error) { +func (c *FakeCertificateSigningRequests) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CertificateSigningRequest, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(certificatesigningrequestsResource, name, pt, data, subresources...), &certificatesv1.CertificateSigningRequest{}) + Invokes(testing.NewRootPatchSubresourceAction(certificatesigningrequestsResource, name, pt, data, subresources...), &v1.CertificateSigningRequest{}) if obj == nil { return nil, err } - return obj.(*certificatesv1.CertificateSigningRequest), err + return obj.(*v1.CertificateSigningRequest), err } // Apply takes the given apply declarative configuration, applies it and returns the applied certificateSigningRequest. -func (c *FakeCertificateSigningRequests) Apply(ctx context.Context, certificateSigningRequest *applyconfigurationscertificatesv1.CertificateSigningRequestApplyConfiguration, opts v1.ApplyOptions) (result *certificatesv1.CertificateSigningRequest, err error) { +func (c *FakeCertificateSigningRequests) Apply(ctx context.Context, certificateSigningRequest *certificatesv1.CertificateSigningRequestApplyConfiguration, opts metav1.ApplyOptions) (result *v1.CertificateSigningRequest, err error) { if certificateSigningRequest == nil { return nil, fmt.Errorf("certificateSigningRequest provided to Apply must not be nil") } @@ -149,16 +148,16 @@ func (c *FakeCertificateSigningRequests) Apply(ctx context.Context, certificateS return nil, fmt.Errorf("certificateSigningRequest.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(certificatesigningrequestsResource, *name, types.ApplyPatchType, data), &certificatesv1.CertificateSigningRequest{}) + Invokes(testing.NewRootPatchSubresourceAction(certificatesigningrequestsResource, *name, types.ApplyPatchType, data), &v1.CertificateSigningRequest{}) if obj == nil { return nil, err } - return obj.(*certificatesv1.CertificateSigningRequest), err + return obj.(*v1.CertificateSigningRequest), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeCertificateSigningRequests) ApplyStatus(ctx context.Context, certificateSigningRequest *applyconfigurationscertificatesv1.CertificateSigningRequestApplyConfiguration, opts v1.ApplyOptions) (result *certificatesv1.CertificateSigningRequest, err error) { +func (c *FakeCertificateSigningRequests) ApplyStatus(ctx context.Context, certificateSigningRequest *certificatesv1.CertificateSigningRequestApplyConfiguration, opts metav1.ApplyOptions) (result *v1.CertificateSigningRequest, err error) { if certificateSigningRequest == nil { return nil, fmt.Errorf("certificateSigningRequest provided to Apply must not be nil") } @@ -171,19 +170,19 @@ func (c *FakeCertificateSigningRequests) ApplyStatus(ctx context.Context, certif return nil, fmt.Errorf("certificateSigningRequest.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(certificatesigningrequestsResource, *name, types.ApplyPatchType, data, "status"), &certificatesv1.CertificateSigningRequest{}) + Invokes(testing.NewRootPatchSubresourceAction(certificatesigningrequestsResource, *name, types.ApplyPatchType, data, "status"), &v1.CertificateSigningRequest{}) if obj == nil { return nil, err } - return obj.(*certificatesv1.CertificateSigningRequest), err + return obj.(*v1.CertificateSigningRequest), err } // UpdateApproval takes the representation of a certificateSigningRequest and updates it. Returns the server's representation of the certificateSigningRequest, and an error, if there is any. -func (c *FakeCertificateSigningRequests) UpdateApproval(ctx context.Context, certificateSigningRequestName string, certificateSigningRequest *certificatesv1.CertificateSigningRequest, opts v1.UpdateOptions) (result *certificatesv1.CertificateSigningRequest, err error) { +func (c *FakeCertificateSigningRequests) UpdateApproval(ctx context.Context, certificateSigningRequestName string, certificateSigningRequest *v1.CertificateSigningRequest, opts metav1.UpdateOptions) (result *v1.CertificateSigningRequest, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateSubresourceAction(certificatesigningrequestsResource, "approval", certificateSigningRequest), &certificatesv1.CertificateSigningRequest{}) + Invokes(testing.NewRootUpdateSubresourceAction(certificatesigningrequestsResource, "approval", certificateSigningRequest), &v1.CertificateSigningRequest{}) if obj == nil { return nil, err } - return obj.(*certificatesv1.CertificateSigningRequest), err + return obj.(*v1.CertificateSigningRequest), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/certificates_client.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/certificates_client.go new file mode 100644 index 0000000000..a9050af945 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/certificates_client.go @@ -0,0 +1,107 @@ +/* +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 v1alpha1 + +import ( + "net/http" + + v1alpha1 "k8s.io/api/certificates/v1alpha1" + "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +type CertificatesV1alpha1Interface interface { + RESTClient() rest.Interface + ClusterTrustBundlesGetter +} + +// CertificatesV1alpha1Client is used to interact with features provided by the certificates.k8s.io group. +type CertificatesV1alpha1Client struct { + restClient rest.Interface +} + +func (c *CertificatesV1alpha1Client) ClusterTrustBundles() ClusterTrustBundleInterface { + return newClusterTrustBundles(c) +} + +// NewForConfig creates a new CertificatesV1alpha1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*CertificatesV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new CertificatesV1alpha1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*CertificatesV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &CertificatesV1alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new CertificatesV1alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *CertificatesV1alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new CertificatesV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *CertificatesV1alpha1Client { + return &CertificatesV1alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *CertificatesV1alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/clustertrustbundle.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/clustertrustbundle.go new file mode 100644 index 0000000000..970fb15e6e --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/clustertrustbundle.go @@ -0,0 +1,197 @@ +/* +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 v1alpha1 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha1 "k8s.io/api/certificates/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + certificatesv1alpha1 "k8s.io/client-go/applyconfigurations/certificates/v1alpha1" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// ClusterTrustBundlesGetter has a method to return a ClusterTrustBundleInterface. +// A group's client should implement this interface. +type ClusterTrustBundlesGetter interface { + ClusterTrustBundles() ClusterTrustBundleInterface +} + +// ClusterTrustBundleInterface has methods to work with ClusterTrustBundle resources. +type ClusterTrustBundleInterface interface { + Create(ctx context.Context, clusterTrustBundle *v1alpha1.ClusterTrustBundle, opts v1.CreateOptions) (*v1alpha1.ClusterTrustBundle, error) + Update(ctx context.Context, clusterTrustBundle *v1alpha1.ClusterTrustBundle, opts v1.UpdateOptions) (*v1alpha1.ClusterTrustBundle, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ClusterTrustBundle, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ClusterTrustBundleList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterTrustBundle, err error) + Apply(ctx context.Context, clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundleApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ClusterTrustBundle, err error) + ClusterTrustBundleExpansion +} + +// clusterTrustBundles implements ClusterTrustBundleInterface +type clusterTrustBundles struct { + client rest.Interface +} + +// newClusterTrustBundles returns a ClusterTrustBundles +func newClusterTrustBundles(c *CertificatesV1alpha1Client) *clusterTrustBundles { + return &clusterTrustBundles{ + client: c.RESTClient(), + } +} + +// Get takes name of the clusterTrustBundle, and returns the corresponding clusterTrustBundle object, and an error if there is any. +func (c *clusterTrustBundles) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + result = &v1alpha1.ClusterTrustBundle{} + err = c.client.Get(). + Resource("clustertrustbundles"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ClusterTrustBundles that match those selectors. +func (c *clusterTrustBundles) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ClusterTrustBundleList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.ClusterTrustBundleList{} + err = c.client.Get(). + Resource("clustertrustbundles"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested clusterTrustBundles. +func (c *clusterTrustBundles) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("clustertrustbundles"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a clusterTrustBundle and creates it. Returns the server's representation of the clusterTrustBundle, and an error, if there is any. +func (c *clusterTrustBundles) Create(ctx context.Context, clusterTrustBundle *v1alpha1.ClusterTrustBundle, opts v1.CreateOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + result = &v1alpha1.ClusterTrustBundle{} + err = c.client.Post(). + Resource("clustertrustbundles"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterTrustBundle). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a clusterTrustBundle and updates it. Returns the server's representation of the clusterTrustBundle, and an error, if there is any. +func (c *clusterTrustBundles) Update(ctx context.Context, clusterTrustBundle *v1alpha1.ClusterTrustBundle, opts v1.UpdateOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + result = &v1alpha1.ClusterTrustBundle{} + err = c.client.Put(). + Resource("clustertrustbundles"). + Name(clusterTrustBundle.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterTrustBundle). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the clusterTrustBundle and deletes it. Returns an error if one occurs. +func (c *clusterTrustBundles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("clustertrustbundles"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *clusterTrustBundles) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("clustertrustbundles"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched clusterTrustBundle. +func (c *clusterTrustBundles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterTrustBundle, err error) { + result = &v1alpha1.ClusterTrustBundle{} + err = c.client.Patch(pt). + Resource("clustertrustbundles"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied clusterTrustBundle. +func (c *clusterTrustBundles) Apply(ctx context.Context, clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundleApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + if clusterTrustBundle == nil { + return nil, fmt.Errorf("clusterTrustBundle provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(clusterTrustBundle) + if err != nil { + return nil, err + } + name := clusterTrustBundle.Name + if name == nil { + return nil, fmt.Errorf("clusterTrustBundle.Name must be provided to Apply") + } + result = &v1alpha1.ClusterTrustBundle{} + err = c.client.Patch(types.ApplyPatchType). + Resource("clustertrustbundles"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/doc.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/doc.go similarity index 100% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/doc.go rename to vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/doc.go diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/doc.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/fake/doc.go similarity index 100% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/doc.go rename to vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/fake/doc.go diff --git a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/fake/fake_certificates_client.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/fake/fake_certificates_client.go new file mode 100644 index 0000000000..8ff02cdbb5 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/fake/fake_certificates_client.go @@ -0,0 +1,40 @@ +/* +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 + +import ( + v1alpha1 "k8s.io/client-go/kubernetes/typed/certificates/v1alpha1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeCertificatesV1alpha1 struct { + *testing.Fake +} + +func (c *FakeCertificatesV1alpha1) ClusterTrustBundles() v1alpha1.ClusterTrustBundleInterface { + return &FakeClusterTrustBundles{c} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeCertificatesV1alpha1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/fake/fake_clustertrustbundle.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/fake/fake_clustertrustbundle.go new file mode 100644 index 0000000000..2f849cbd7d --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/fake/fake_clustertrustbundle.go @@ -0,0 +1,145 @@ +/* +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 + +import ( + "context" + json "encoding/json" + "fmt" + + v1alpha1 "k8s.io/api/certificates/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + certificatesv1alpha1 "k8s.io/client-go/applyconfigurations/certificates/v1alpha1" + testing "k8s.io/client-go/testing" +) + +// FakeClusterTrustBundles implements ClusterTrustBundleInterface +type FakeClusterTrustBundles struct { + Fake *FakeCertificatesV1alpha1 +} + +var clustertrustbundlesResource = v1alpha1.SchemeGroupVersion.WithResource("clustertrustbundles") + +var clustertrustbundlesKind = v1alpha1.SchemeGroupVersion.WithKind("ClusterTrustBundle") + +// Get takes name of the clusterTrustBundle, and returns the corresponding clusterTrustBundle object, and an error if there is any. +func (c *FakeClusterTrustBundles) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(clustertrustbundlesResource, name), &v1alpha1.ClusterTrustBundle{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterTrustBundle), err +} + +// List takes label and field selectors, and returns the list of ClusterTrustBundles that match those selectors. +func (c *FakeClusterTrustBundles) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ClusterTrustBundleList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(clustertrustbundlesResource, clustertrustbundlesKind, opts), &v1alpha1.ClusterTrustBundleList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.ClusterTrustBundleList{ListMeta: obj.(*v1alpha1.ClusterTrustBundleList).ListMeta} + for _, item := range obj.(*v1alpha1.ClusterTrustBundleList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested clusterTrustBundles. +func (c *FakeClusterTrustBundles) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(clustertrustbundlesResource, opts)) +} + +// Create takes the representation of a clusterTrustBundle and creates it. Returns the server's representation of the clusterTrustBundle, and an error, if there is any. +func (c *FakeClusterTrustBundles) Create(ctx context.Context, clusterTrustBundle *v1alpha1.ClusterTrustBundle, opts v1.CreateOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(clustertrustbundlesResource, clusterTrustBundle), &v1alpha1.ClusterTrustBundle{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterTrustBundle), err +} + +// Update takes the representation of a clusterTrustBundle and updates it. Returns the server's representation of the clusterTrustBundle, and an error, if there is any. +func (c *FakeClusterTrustBundles) Update(ctx context.Context, clusterTrustBundle *v1alpha1.ClusterTrustBundle, opts v1.UpdateOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(clustertrustbundlesResource, clusterTrustBundle), &v1alpha1.ClusterTrustBundle{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterTrustBundle), err +} + +// Delete takes name of the clusterTrustBundle and deletes it. Returns an error if one occurs. +func (c *FakeClusterTrustBundles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteActionWithOptions(clustertrustbundlesResource, name, opts), &v1alpha1.ClusterTrustBundle{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeClusterTrustBundles) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(clustertrustbundlesResource, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha1.ClusterTrustBundleList{}) + return err +} + +// Patch applies the patch and returns the patched clusterTrustBundle. +func (c *FakeClusterTrustBundles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterTrustBundle, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(clustertrustbundlesResource, name, pt, data, subresources...), &v1alpha1.ClusterTrustBundle{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterTrustBundle), err +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied clusterTrustBundle. +func (c *FakeClusterTrustBundles) Apply(ctx context.Context, clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundleApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + if clusterTrustBundle == nil { + return nil, fmt.Errorf("clusterTrustBundle provided to Apply must not be nil") + } + data, err := json.Marshal(clusterTrustBundle) + if err != nil { + return nil, err + } + name := clusterTrustBundle.Name + if name == nil { + return nil, fmt.Errorf("clusterTrustBundle.Name must be provided to Apply") + } + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(clustertrustbundlesResource, *name, types.ApplyPatchType, data), &v1alpha1.ClusterTrustBundle{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterTrustBundle), err +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/generated_expansion.go new file mode 100644 index 0000000000..43cc534b37 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +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 v1alpha1 + +type ClusterTrustBundleExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1beta1/fake/fake_certificatesigningrequest.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1beta1/fake/fake_certificatesigningrequest.go index 5a416150a8..76bb38e7bf 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1beta1/fake/fake_certificatesigningrequest.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1beta1/fake/fake_certificatesigningrequest.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/certificates/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" certificatesv1beta1 "k8s.io/client-go/applyconfigurations/certificates/v1beta1" @@ -38,9 +37,9 @@ type FakeCertificateSigningRequests struct { Fake *FakeCertificatesV1beta1 } -var certificatesigningrequestsResource = schema.GroupVersionResource{Group: "certificates.k8s.io", Version: "v1beta1", Resource: "certificatesigningrequests"} +var certificatesigningrequestsResource = v1beta1.SchemeGroupVersion.WithResource("certificatesigningrequests") -var certificatesigningrequestsKind = schema.GroupVersionKind{Group: "certificates.k8s.io", Version: "v1beta1", Kind: "CertificateSigningRequest"} +var certificatesigningrequestsKind = v1beta1.SchemeGroupVersion.WithKind("CertificateSigningRequest") // Get takes name of the certificateSigningRequest, and returns the corresponding certificateSigningRequest object, and an error if there is any. func (c *FakeCertificateSigningRequests) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.CertificateSigningRequest, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/coordination/v1/fake/fake_lease.go b/vendor/k8s.io/client-go/kubernetes/typed/coordination/v1/fake/fake_lease.go index c52c828ef4..6dc7c4c17f 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/coordination/v1/fake/fake_lease.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/coordination/v1/fake/fake_lease.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - coordinationv1 "k8s.io/api/coordination/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/coordination/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscoordinationv1 "k8s.io/client-go/applyconfigurations/coordination/v1" + coordinationv1 "k8s.io/client-go/applyconfigurations/coordination/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeLeases struct { ns string } -var leasesResource = schema.GroupVersionResource{Group: "coordination.k8s.io", Version: "v1", Resource: "leases"} +var leasesResource = v1.SchemeGroupVersion.WithResource("leases") -var leasesKind = schema.GroupVersionKind{Group: "coordination.k8s.io", Version: "v1", Kind: "Lease"} +var leasesKind = v1.SchemeGroupVersion.WithKind("Lease") // Get takes name of the lease, and returns the corresponding lease object, and an error if there is any. -func (c *FakeLeases) Get(ctx context.Context, name string, options v1.GetOptions) (result *coordinationv1.Lease, err error) { +func (c *FakeLeases) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Lease, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(leasesResource, c.ns, name), &coordinationv1.Lease{}) + Invokes(testing.NewGetAction(leasesResource, c.ns, name), &v1.Lease{}) if obj == nil { return nil, err } - return obj.(*coordinationv1.Lease), err + return obj.(*v1.Lease), err } // List takes label and field selectors, and returns the list of Leases that match those selectors. -func (c *FakeLeases) List(ctx context.Context, opts v1.ListOptions) (result *coordinationv1.LeaseList, err error) { +func (c *FakeLeases) List(ctx context.Context, opts metav1.ListOptions) (result *v1.LeaseList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(leasesResource, leasesKind, c.ns, opts), &coordinationv1.LeaseList{}) + Invokes(testing.NewListAction(leasesResource, leasesKind, c.ns, opts), &v1.LeaseList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeLeases) List(ctx context.Context, opts v1.ListOptions) (result *coo if label == nil { label = labels.Everything() } - list := &coordinationv1.LeaseList{ListMeta: obj.(*coordinationv1.LeaseList).ListMeta} - for _, item := range obj.(*coordinationv1.LeaseList).Items { + list := &v1.LeaseList{ListMeta: obj.(*v1.LeaseList).ListMeta} + for _, item := range obj.(*v1.LeaseList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,63 +76,63 @@ func (c *FakeLeases) List(ctx context.Context, opts v1.ListOptions) (result *coo } // Watch returns a watch.Interface that watches the requested leases. -func (c *FakeLeases) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeLeases) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(leasesResource, c.ns, opts)) } // Create takes the representation of a lease and creates it. Returns the server's representation of the lease, and an error, if there is any. -func (c *FakeLeases) Create(ctx context.Context, lease *coordinationv1.Lease, opts v1.CreateOptions) (result *coordinationv1.Lease, err error) { +func (c *FakeLeases) Create(ctx context.Context, lease *v1.Lease, opts metav1.CreateOptions) (result *v1.Lease, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(leasesResource, c.ns, lease), &coordinationv1.Lease{}) + Invokes(testing.NewCreateAction(leasesResource, c.ns, lease), &v1.Lease{}) if obj == nil { return nil, err } - return obj.(*coordinationv1.Lease), err + return obj.(*v1.Lease), err } // Update takes the representation of a lease and updates it. Returns the server's representation of the lease, and an error, if there is any. -func (c *FakeLeases) Update(ctx context.Context, lease *coordinationv1.Lease, opts v1.UpdateOptions) (result *coordinationv1.Lease, err error) { +func (c *FakeLeases) Update(ctx context.Context, lease *v1.Lease, opts metav1.UpdateOptions) (result *v1.Lease, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(leasesResource, c.ns, lease), &coordinationv1.Lease{}) + Invokes(testing.NewUpdateAction(leasesResource, c.ns, lease), &v1.Lease{}) if obj == nil { return nil, err } - return obj.(*coordinationv1.Lease), err + return obj.(*v1.Lease), err } // Delete takes name of the lease and deletes it. Returns an error if one occurs. -func (c *FakeLeases) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeLeases) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(leasesResource, c.ns, name, opts), &coordinationv1.Lease{}) + Invokes(testing.NewDeleteActionWithOptions(leasesResource, c.ns, name, opts), &v1.Lease{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeLeases) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeLeases) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(leasesResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &coordinationv1.LeaseList{}) + _, err := c.Fake.Invokes(action, &v1.LeaseList{}) return err } // Patch applies the patch and returns the patched lease. -func (c *FakeLeases) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *coordinationv1.Lease, err error) { +func (c *FakeLeases) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Lease, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(leasesResource, c.ns, name, pt, data, subresources...), &coordinationv1.Lease{}) + Invokes(testing.NewPatchSubresourceAction(leasesResource, c.ns, name, pt, data, subresources...), &v1.Lease{}) if obj == nil { return nil, err } - return obj.(*coordinationv1.Lease), err + return obj.(*v1.Lease), err } // Apply takes the given apply declarative configuration, applies it and returns the applied lease. -func (c *FakeLeases) Apply(ctx context.Context, lease *applyconfigurationscoordinationv1.LeaseApplyConfiguration, opts v1.ApplyOptions) (result *coordinationv1.Lease, err error) { +func (c *FakeLeases) Apply(ctx context.Context, lease *coordinationv1.LeaseApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Lease, err error) { if lease == nil { return nil, fmt.Errorf("lease provided to Apply must not be nil") } @@ -146,10 +145,10 @@ func (c *FakeLeases) Apply(ctx context.Context, lease *applyconfigurationscoordi return nil, fmt.Errorf("lease.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(leasesResource, c.ns, *name, types.ApplyPatchType, data), &coordinationv1.Lease{}) + Invokes(testing.NewPatchSubresourceAction(leasesResource, c.ns, *name, types.ApplyPatchType, data), &v1.Lease{}) if obj == nil { return nil, err } - return obj.(*coordinationv1.Lease), err + return obj.(*v1.Lease), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/coordination/v1beta1/fake/fake_lease.go b/vendor/k8s.io/client-go/kubernetes/typed/coordination/v1beta1/fake/fake_lease.go index 15b6c401dc..9a4a0d7eb9 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/coordination/v1beta1/fake/fake_lease.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/coordination/v1beta1/fake/fake_lease.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/coordination/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" coordinationv1beta1 "k8s.io/client-go/applyconfigurations/coordination/v1beta1" @@ -39,9 +38,9 @@ type FakeLeases struct { ns string } -var leasesResource = schema.GroupVersionResource{Group: "coordination.k8s.io", Version: "v1beta1", Resource: "leases"} +var leasesResource = v1beta1.SchemeGroupVersion.WithResource("leases") -var leasesKind = schema.GroupVersionKind{Group: "coordination.k8s.io", Version: "v1beta1", Kind: "Lease"} +var leasesKind = v1beta1.SchemeGroupVersion.WithKind("Lease") // Get takes name of the lease, and returns the corresponding lease object, and an error if there is any. func (c *FakeLeases) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Lease, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_componentstatus.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_componentstatus.go index 7e5c02daac..39d4c3282e 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_componentstatus.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_componentstatus.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakeComponentStatuses struct { Fake *FakeCoreV1 } -var componentstatusesResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "componentstatuses"} +var componentstatusesResource = v1.SchemeGroupVersion.WithResource("componentstatuses") -var componentstatusesKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "ComponentStatus"} +var componentstatusesKind = v1.SchemeGroupVersion.WithKind("ComponentStatus") // Get takes name of the componentStatus, and returns the corresponding componentStatus object, and an error if there is any. -func (c *FakeComponentStatuses) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.ComponentStatus, err error) { +func (c *FakeComponentStatuses) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ComponentStatus, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(componentstatusesResource, name), &corev1.ComponentStatus{}) + Invokes(testing.NewRootGetAction(componentstatusesResource, name), &v1.ComponentStatus{}) if obj == nil { return nil, err } - return obj.(*corev1.ComponentStatus), err + return obj.(*v1.ComponentStatus), err } // List takes label and field selectors, and returns the list of ComponentStatuses that match those selectors. -func (c *FakeComponentStatuses) List(ctx context.Context, opts v1.ListOptions) (result *corev1.ComponentStatusList, err error) { +func (c *FakeComponentStatuses) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ComponentStatusList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(componentstatusesResource, componentstatusesKind, opts), &corev1.ComponentStatusList{}) + Invokes(testing.NewRootListAction(componentstatusesResource, componentstatusesKind, opts), &v1.ComponentStatusList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakeComponentStatuses) List(ctx context.Context, opts v1.ListOptions) ( if label == nil { label = labels.Everything() } - list := &corev1.ComponentStatusList{ListMeta: obj.(*corev1.ComponentStatusList).ListMeta} - for _, item := range obj.(*corev1.ComponentStatusList).Items { + list := &v1.ComponentStatusList{ListMeta: obj.(*v1.ComponentStatusList).ListMeta} + for _, item := range obj.(*v1.ComponentStatusList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,58 +73,58 @@ func (c *FakeComponentStatuses) List(ctx context.Context, opts v1.ListOptions) ( } // Watch returns a watch.Interface that watches the requested componentStatuses. -func (c *FakeComponentStatuses) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeComponentStatuses) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(componentstatusesResource, opts)) } // Create takes the representation of a componentStatus and creates it. Returns the server's representation of the componentStatus, and an error, if there is any. -func (c *FakeComponentStatuses) Create(ctx context.Context, componentStatus *corev1.ComponentStatus, opts v1.CreateOptions) (result *corev1.ComponentStatus, err error) { +func (c *FakeComponentStatuses) Create(ctx context.Context, componentStatus *v1.ComponentStatus, opts metav1.CreateOptions) (result *v1.ComponentStatus, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(componentstatusesResource, componentStatus), &corev1.ComponentStatus{}) + Invokes(testing.NewRootCreateAction(componentstatusesResource, componentStatus), &v1.ComponentStatus{}) if obj == nil { return nil, err } - return obj.(*corev1.ComponentStatus), err + return obj.(*v1.ComponentStatus), err } // Update takes the representation of a componentStatus and updates it. Returns the server's representation of the componentStatus, and an error, if there is any. -func (c *FakeComponentStatuses) Update(ctx context.Context, componentStatus *corev1.ComponentStatus, opts v1.UpdateOptions) (result *corev1.ComponentStatus, err error) { +func (c *FakeComponentStatuses) Update(ctx context.Context, componentStatus *v1.ComponentStatus, opts metav1.UpdateOptions) (result *v1.ComponentStatus, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(componentstatusesResource, componentStatus), &corev1.ComponentStatus{}) + Invokes(testing.NewRootUpdateAction(componentstatusesResource, componentStatus), &v1.ComponentStatus{}) if obj == nil { return nil, err } - return obj.(*corev1.ComponentStatus), err + return obj.(*v1.ComponentStatus), err } // Delete takes name of the componentStatus and deletes it. Returns an error if one occurs. -func (c *FakeComponentStatuses) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeComponentStatuses) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(componentstatusesResource, name, opts), &corev1.ComponentStatus{}) + Invokes(testing.NewRootDeleteActionWithOptions(componentstatusesResource, name, opts), &v1.ComponentStatus{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeComponentStatuses) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeComponentStatuses) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(componentstatusesResource, listOpts) - _, err := c.Fake.Invokes(action, &corev1.ComponentStatusList{}) + _, err := c.Fake.Invokes(action, &v1.ComponentStatusList{}) return err } // Patch applies the patch and returns the patched componentStatus. -func (c *FakeComponentStatuses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.ComponentStatus, err error) { +func (c *FakeComponentStatuses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ComponentStatus, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(componentstatusesResource, name, pt, data, subresources...), &corev1.ComponentStatus{}) + Invokes(testing.NewRootPatchSubresourceAction(componentstatusesResource, name, pt, data, subresources...), &v1.ComponentStatus{}) if obj == nil { return nil, err } - return obj.(*corev1.ComponentStatus), err + return obj.(*v1.ComponentStatus), err } // Apply takes the given apply declarative configuration, applies it and returns the applied componentStatus. -func (c *FakeComponentStatuses) Apply(ctx context.Context, componentStatus *applyconfigurationscorev1.ComponentStatusApplyConfiguration, opts v1.ApplyOptions) (result *corev1.ComponentStatus, err error) { +func (c *FakeComponentStatuses) Apply(ctx context.Context, componentStatus *corev1.ComponentStatusApplyConfiguration, opts metav1.ApplyOptions) (result *v1.ComponentStatus, err error) { if componentStatus == nil { return nil, fmt.Errorf("componentStatus provided to Apply must not be nil") } @@ -138,9 +137,9 @@ func (c *FakeComponentStatuses) Apply(ctx context.Context, componentStatus *appl return nil, fmt.Errorf("componentStatus.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(componentstatusesResource, *name, types.ApplyPatchType, data), &corev1.ComponentStatus{}) + Invokes(testing.NewRootPatchSubresourceAction(componentstatusesResource, *name, types.ApplyPatchType, data), &v1.ComponentStatus{}) if obj == nil { return nil, err } - return obj.(*corev1.ComponentStatus), err + return obj.(*v1.ComponentStatus), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_configmap.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_configmap.go index b74b376a92..6e8a38bd8f 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_configmap.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_configmap.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeConfigMaps struct { ns string } -var configmapsResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "configmaps"} +var configmapsResource = v1.SchemeGroupVersion.WithResource("configmaps") -var configmapsKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "ConfigMap"} +var configmapsKind = v1.SchemeGroupVersion.WithKind("ConfigMap") // Get takes name of the configMap, and returns the corresponding configMap object, and an error if there is any. -func (c *FakeConfigMaps) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.ConfigMap, err error) { +func (c *FakeConfigMaps) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ConfigMap, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(configmapsResource, c.ns, name), &corev1.ConfigMap{}) + Invokes(testing.NewGetAction(configmapsResource, c.ns, name), &v1.ConfigMap{}) if obj == nil { return nil, err } - return obj.(*corev1.ConfigMap), err + return obj.(*v1.ConfigMap), err } // List takes label and field selectors, and returns the list of ConfigMaps that match those selectors. -func (c *FakeConfigMaps) List(ctx context.Context, opts v1.ListOptions) (result *corev1.ConfigMapList, err error) { +func (c *FakeConfigMaps) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ConfigMapList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(configmapsResource, configmapsKind, c.ns, opts), &corev1.ConfigMapList{}) + Invokes(testing.NewListAction(configmapsResource, configmapsKind, c.ns, opts), &v1.ConfigMapList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeConfigMaps) List(ctx context.Context, opts v1.ListOptions) (result if label == nil { label = labels.Everything() } - list := &corev1.ConfigMapList{ListMeta: obj.(*corev1.ConfigMapList).ListMeta} - for _, item := range obj.(*corev1.ConfigMapList).Items { + list := &v1.ConfigMapList{ListMeta: obj.(*v1.ConfigMapList).ListMeta} + for _, item := range obj.(*v1.ConfigMapList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,63 +76,63 @@ func (c *FakeConfigMaps) List(ctx context.Context, opts v1.ListOptions) (result } // Watch returns a watch.Interface that watches the requested configMaps. -func (c *FakeConfigMaps) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeConfigMaps) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(configmapsResource, c.ns, opts)) } // Create takes the representation of a configMap and creates it. Returns the server's representation of the configMap, and an error, if there is any. -func (c *FakeConfigMaps) Create(ctx context.Context, configMap *corev1.ConfigMap, opts v1.CreateOptions) (result *corev1.ConfigMap, err error) { +func (c *FakeConfigMaps) Create(ctx context.Context, configMap *v1.ConfigMap, opts metav1.CreateOptions) (result *v1.ConfigMap, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(configmapsResource, c.ns, configMap), &corev1.ConfigMap{}) + Invokes(testing.NewCreateAction(configmapsResource, c.ns, configMap), &v1.ConfigMap{}) if obj == nil { return nil, err } - return obj.(*corev1.ConfigMap), err + return obj.(*v1.ConfigMap), err } // Update takes the representation of a configMap and updates it. Returns the server's representation of the configMap, and an error, if there is any. -func (c *FakeConfigMaps) Update(ctx context.Context, configMap *corev1.ConfigMap, opts v1.UpdateOptions) (result *corev1.ConfigMap, err error) { +func (c *FakeConfigMaps) Update(ctx context.Context, configMap *v1.ConfigMap, opts metav1.UpdateOptions) (result *v1.ConfigMap, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(configmapsResource, c.ns, configMap), &corev1.ConfigMap{}) + Invokes(testing.NewUpdateAction(configmapsResource, c.ns, configMap), &v1.ConfigMap{}) if obj == nil { return nil, err } - return obj.(*corev1.ConfigMap), err + return obj.(*v1.ConfigMap), err } // Delete takes name of the configMap and deletes it. Returns an error if one occurs. -func (c *FakeConfigMaps) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeConfigMaps) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(configmapsResource, c.ns, name, opts), &corev1.ConfigMap{}) + Invokes(testing.NewDeleteActionWithOptions(configmapsResource, c.ns, name, opts), &v1.ConfigMap{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeConfigMaps) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeConfigMaps) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(configmapsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &corev1.ConfigMapList{}) + _, err := c.Fake.Invokes(action, &v1.ConfigMapList{}) return err } // Patch applies the patch and returns the patched configMap. -func (c *FakeConfigMaps) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.ConfigMap, err error) { +func (c *FakeConfigMaps) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ConfigMap, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(configmapsResource, c.ns, name, pt, data, subresources...), &corev1.ConfigMap{}) + Invokes(testing.NewPatchSubresourceAction(configmapsResource, c.ns, name, pt, data, subresources...), &v1.ConfigMap{}) if obj == nil { return nil, err } - return obj.(*corev1.ConfigMap), err + return obj.(*v1.ConfigMap), err } // Apply takes the given apply declarative configuration, applies it and returns the applied configMap. -func (c *FakeConfigMaps) Apply(ctx context.Context, configMap *applyconfigurationscorev1.ConfigMapApplyConfiguration, opts v1.ApplyOptions) (result *corev1.ConfigMap, err error) { +func (c *FakeConfigMaps) Apply(ctx context.Context, configMap *corev1.ConfigMapApplyConfiguration, opts metav1.ApplyOptions) (result *v1.ConfigMap, err error) { if configMap == nil { return nil, fmt.Errorf("configMap provided to Apply must not be nil") } @@ -146,10 +145,10 @@ func (c *FakeConfigMaps) Apply(ctx context.Context, configMap *applyconfiguratio return nil, fmt.Errorf("configMap.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(configmapsResource, c.ns, *name, types.ApplyPatchType, data), &corev1.ConfigMap{}) + Invokes(testing.NewPatchSubresourceAction(configmapsResource, c.ns, *name, types.ApplyPatchType, data), &v1.ConfigMap{}) if obj == nil { return nil, err } - return obj.(*corev1.ConfigMap), err + return obj.(*v1.ConfigMap), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_endpoints.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_endpoints.go index e9a515a1af..6b2f6c249e 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_endpoints.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_endpoints.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeEndpoints struct { ns string } -var endpointsResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "endpoints"} +var endpointsResource = v1.SchemeGroupVersion.WithResource("endpoints") -var endpointsKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Endpoints"} +var endpointsKind = v1.SchemeGroupVersion.WithKind("Endpoints") // Get takes name of the endpoints, and returns the corresponding endpoints object, and an error if there is any. -func (c *FakeEndpoints) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.Endpoints, err error) { +func (c *FakeEndpoints) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Endpoints, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(endpointsResource, c.ns, name), &corev1.Endpoints{}) + Invokes(testing.NewGetAction(endpointsResource, c.ns, name), &v1.Endpoints{}) if obj == nil { return nil, err } - return obj.(*corev1.Endpoints), err + return obj.(*v1.Endpoints), err } // List takes label and field selectors, and returns the list of Endpoints that match those selectors. -func (c *FakeEndpoints) List(ctx context.Context, opts v1.ListOptions) (result *corev1.EndpointsList, err error) { +func (c *FakeEndpoints) List(ctx context.Context, opts metav1.ListOptions) (result *v1.EndpointsList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(endpointsResource, endpointsKind, c.ns, opts), &corev1.EndpointsList{}) + Invokes(testing.NewListAction(endpointsResource, endpointsKind, c.ns, opts), &v1.EndpointsList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeEndpoints) List(ctx context.Context, opts v1.ListOptions) (result * if label == nil { label = labels.Everything() } - list := &corev1.EndpointsList{ListMeta: obj.(*corev1.EndpointsList).ListMeta} - for _, item := range obj.(*corev1.EndpointsList).Items { + list := &v1.EndpointsList{ListMeta: obj.(*v1.EndpointsList).ListMeta} + for _, item := range obj.(*v1.EndpointsList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,63 +76,63 @@ func (c *FakeEndpoints) List(ctx context.Context, opts v1.ListOptions) (result * } // Watch returns a watch.Interface that watches the requested endpoints. -func (c *FakeEndpoints) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeEndpoints) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(endpointsResource, c.ns, opts)) } // Create takes the representation of a endpoints and creates it. Returns the server's representation of the endpoints, and an error, if there is any. -func (c *FakeEndpoints) Create(ctx context.Context, endpoints *corev1.Endpoints, opts v1.CreateOptions) (result *corev1.Endpoints, err error) { +func (c *FakeEndpoints) Create(ctx context.Context, endpoints *v1.Endpoints, opts metav1.CreateOptions) (result *v1.Endpoints, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(endpointsResource, c.ns, endpoints), &corev1.Endpoints{}) + Invokes(testing.NewCreateAction(endpointsResource, c.ns, endpoints), &v1.Endpoints{}) if obj == nil { return nil, err } - return obj.(*corev1.Endpoints), err + return obj.(*v1.Endpoints), err } // Update takes the representation of a endpoints and updates it. Returns the server's representation of the endpoints, and an error, if there is any. -func (c *FakeEndpoints) Update(ctx context.Context, endpoints *corev1.Endpoints, opts v1.UpdateOptions) (result *corev1.Endpoints, err error) { +func (c *FakeEndpoints) Update(ctx context.Context, endpoints *v1.Endpoints, opts metav1.UpdateOptions) (result *v1.Endpoints, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(endpointsResource, c.ns, endpoints), &corev1.Endpoints{}) + Invokes(testing.NewUpdateAction(endpointsResource, c.ns, endpoints), &v1.Endpoints{}) if obj == nil { return nil, err } - return obj.(*corev1.Endpoints), err + return obj.(*v1.Endpoints), err } // Delete takes name of the endpoints and deletes it. Returns an error if one occurs. -func (c *FakeEndpoints) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeEndpoints) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(endpointsResource, c.ns, name, opts), &corev1.Endpoints{}) + Invokes(testing.NewDeleteActionWithOptions(endpointsResource, c.ns, name, opts), &v1.Endpoints{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeEndpoints) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeEndpoints) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(endpointsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &corev1.EndpointsList{}) + _, err := c.Fake.Invokes(action, &v1.EndpointsList{}) return err } // Patch applies the patch and returns the patched endpoints. -func (c *FakeEndpoints) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.Endpoints, err error) { +func (c *FakeEndpoints) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Endpoints, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(endpointsResource, c.ns, name, pt, data, subresources...), &corev1.Endpoints{}) + Invokes(testing.NewPatchSubresourceAction(endpointsResource, c.ns, name, pt, data, subresources...), &v1.Endpoints{}) if obj == nil { return nil, err } - return obj.(*corev1.Endpoints), err + return obj.(*v1.Endpoints), err } // Apply takes the given apply declarative configuration, applies it and returns the applied endpoints. -func (c *FakeEndpoints) Apply(ctx context.Context, endpoints *applyconfigurationscorev1.EndpointsApplyConfiguration, opts v1.ApplyOptions) (result *corev1.Endpoints, err error) { +func (c *FakeEndpoints) Apply(ctx context.Context, endpoints *corev1.EndpointsApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Endpoints, err error) { if endpoints == nil { return nil, fmt.Errorf("endpoints provided to Apply must not be nil") } @@ -146,10 +145,10 @@ func (c *FakeEndpoints) Apply(ctx context.Context, endpoints *applyconfiguration return nil, fmt.Errorf("endpoints.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(endpointsResource, c.ns, *name, types.ApplyPatchType, data), &corev1.Endpoints{}) + Invokes(testing.NewPatchSubresourceAction(endpointsResource, c.ns, *name, types.ApplyPatchType, data), &v1.Endpoints{}) if obj == nil { return nil, err } - return obj.(*corev1.Endpoints), err + return obj.(*v1.Endpoints), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_event.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_event.go index 9518839431..9ad879b394 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_event.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_event.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeEvents struct { ns string } -var eventsResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "events"} +var eventsResource = v1.SchemeGroupVersion.WithResource("events") -var eventsKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Event"} +var eventsKind = v1.SchemeGroupVersion.WithKind("Event") // Get takes name of the event, and returns the corresponding event object, and an error if there is any. -func (c *FakeEvents) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.Event, err error) { +func (c *FakeEvents) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Event, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(eventsResource, c.ns, name), &corev1.Event{}) + Invokes(testing.NewGetAction(eventsResource, c.ns, name), &v1.Event{}) if obj == nil { return nil, err } - return obj.(*corev1.Event), err + return obj.(*v1.Event), err } // List takes label and field selectors, and returns the list of Events that match those selectors. -func (c *FakeEvents) List(ctx context.Context, opts v1.ListOptions) (result *corev1.EventList, err error) { +func (c *FakeEvents) List(ctx context.Context, opts metav1.ListOptions) (result *v1.EventList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(eventsResource, eventsKind, c.ns, opts), &corev1.EventList{}) + Invokes(testing.NewListAction(eventsResource, eventsKind, c.ns, opts), &v1.EventList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeEvents) List(ctx context.Context, opts v1.ListOptions) (result *cor if label == nil { label = labels.Everything() } - list := &corev1.EventList{ListMeta: obj.(*corev1.EventList).ListMeta} - for _, item := range obj.(*corev1.EventList).Items { + list := &v1.EventList{ListMeta: obj.(*v1.EventList).ListMeta} + for _, item := range obj.(*v1.EventList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,63 +76,63 @@ func (c *FakeEvents) List(ctx context.Context, opts v1.ListOptions) (result *cor } // Watch returns a watch.Interface that watches the requested events. -func (c *FakeEvents) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeEvents) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(eventsResource, c.ns, opts)) } // Create takes the representation of a event and creates it. Returns the server's representation of the event, and an error, if there is any. -func (c *FakeEvents) Create(ctx context.Context, event *corev1.Event, opts v1.CreateOptions) (result *corev1.Event, err error) { +func (c *FakeEvents) Create(ctx context.Context, event *v1.Event, opts metav1.CreateOptions) (result *v1.Event, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(eventsResource, c.ns, event), &corev1.Event{}) + Invokes(testing.NewCreateAction(eventsResource, c.ns, event), &v1.Event{}) if obj == nil { return nil, err } - return obj.(*corev1.Event), err + return obj.(*v1.Event), err } // Update takes the representation of a event and updates it. Returns the server's representation of the event, and an error, if there is any. -func (c *FakeEvents) Update(ctx context.Context, event *corev1.Event, opts v1.UpdateOptions) (result *corev1.Event, err error) { +func (c *FakeEvents) Update(ctx context.Context, event *v1.Event, opts metav1.UpdateOptions) (result *v1.Event, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(eventsResource, c.ns, event), &corev1.Event{}) + Invokes(testing.NewUpdateAction(eventsResource, c.ns, event), &v1.Event{}) if obj == nil { return nil, err } - return obj.(*corev1.Event), err + return obj.(*v1.Event), err } // Delete takes name of the event and deletes it. Returns an error if one occurs. -func (c *FakeEvents) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeEvents) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(eventsResource, c.ns, name, opts), &corev1.Event{}) + Invokes(testing.NewDeleteActionWithOptions(eventsResource, c.ns, name, opts), &v1.Event{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeEvents) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeEvents) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(eventsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &corev1.EventList{}) + _, err := c.Fake.Invokes(action, &v1.EventList{}) return err } // Patch applies the patch and returns the patched event. -func (c *FakeEvents) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.Event, err error) { +func (c *FakeEvents) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Event, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(eventsResource, c.ns, name, pt, data, subresources...), &corev1.Event{}) + Invokes(testing.NewPatchSubresourceAction(eventsResource, c.ns, name, pt, data, subresources...), &v1.Event{}) if obj == nil { return nil, err } - return obj.(*corev1.Event), err + return obj.(*v1.Event), err } // Apply takes the given apply declarative configuration, applies it and returns the applied event. -func (c *FakeEvents) Apply(ctx context.Context, event *applyconfigurationscorev1.EventApplyConfiguration, opts v1.ApplyOptions) (result *corev1.Event, err error) { +func (c *FakeEvents) Apply(ctx context.Context, event *corev1.EventApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Event, err error) { if event == nil { return nil, fmt.Errorf("event provided to Apply must not be nil") } @@ -146,10 +145,10 @@ func (c *FakeEvents) Apply(ctx context.Context, event *applyconfigurationscorev1 return nil, fmt.Errorf("event.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(eventsResource, c.ns, *name, types.ApplyPatchType, data), &corev1.Event{}) + Invokes(testing.NewPatchSubresourceAction(eventsResource, c.ns, *name, types.ApplyPatchType, data), &v1.Event{}) if obj == nil { return nil, err } - return obj.(*corev1.Event), err + return obj.(*v1.Event), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_limitrange.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_limitrange.go index 7487285e91..f18b5741c3 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_limitrange.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_limitrange.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeLimitRanges struct { ns string } -var limitrangesResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "limitranges"} +var limitrangesResource = v1.SchemeGroupVersion.WithResource("limitranges") -var limitrangesKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "LimitRange"} +var limitrangesKind = v1.SchemeGroupVersion.WithKind("LimitRange") // Get takes name of the limitRange, and returns the corresponding limitRange object, and an error if there is any. -func (c *FakeLimitRanges) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.LimitRange, err error) { +func (c *FakeLimitRanges) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.LimitRange, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(limitrangesResource, c.ns, name), &corev1.LimitRange{}) + Invokes(testing.NewGetAction(limitrangesResource, c.ns, name), &v1.LimitRange{}) if obj == nil { return nil, err } - return obj.(*corev1.LimitRange), err + return obj.(*v1.LimitRange), err } // List takes label and field selectors, and returns the list of LimitRanges that match those selectors. -func (c *FakeLimitRanges) List(ctx context.Context, opts v1.ListOptions) (result *corev1.LimitRangeList, err error) { +func (c *FakeLimitRanges) List(ctx context.Context, opts metav1.ListOptions) (result *v1.LimitRangeList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(limitrangesResource, limitrangesKind, c.ns, opts), &corev1.LimitRangeList{}) + Invokes(testing.NewListAction(limitrangesResource, limitrangesKind, c.ns, opts), &v1.LimitRangeList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeLimitRanges) List(ctx context.Context, opts v1.ListOptions) (result if label == nil { label = labels.Everything() } - list := &corev1.LimitRangeList{ListMeta: obj.(*corev1.LimitRangeList).ListMeta} - for _, item := range obj.(*corev1.LimitRangeList).Items { + list := &v1.LimitRangeList{ListMeta: obj.(*v1.LimitRangeList).ListMeta} + for _, item := range obj.(*v1.LimitRangeList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,63 +76,63 @@ func (c *FakeLimitRanges) List(ctx context.Context, opts v1.ListOptions) (result } // Watch returns a watch.Interface that watches the requested limitRanges. -func (c *FakeLimitRanges) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeLimitRanges) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(limitrangesResource, c.ns, opts)) } // Create takes the representation of a limitRange and creates it. Returns the server's representation of the limitRange, and an error, if there is any. -func (c *FakeLimitRanges) Create(ctx context.Context, limitRange *corev1.LimitRange, opts v1.CreateOptions) (result *corev1.LimitRange, err error) { +func (c *FakeLimitRanges) Create(ctx context.Context, limitRange *v1.LimitRange, opts metav1.CreateOptions) (result *v1.LimitRange, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(limitrangesResource, c.ns, limitRange), &corev1.LimitRange{}) + Invokes(testing.NewCreateAction(limitrangesResource, c.ns, limitRange), &v1.LimitRange{}) if obj == nil { return nil, err } - return obj.(*corev1.LimitRange), err + return obj.(*v1.LimitRange), err } // Update takes the representation of a limitRange and updates it. Returns the server's representation of the limitRange, and an error, if there is any. -func (c *FakeLimitRanges) Update(ctx context.Context, limitRange *corev1.LimitRange, opts v1.UpdateOptions) (result *corev1.LimitRange, err error) { +func (c *FakeLimitRanges) Update(ctx context.Context, limitRange *v1.LimitRange, opts metav1.UpdateOptions) (result *v1.LimitRange, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(limitrangesResource, c.ns, limitRange), &corev1.LimitRange{}) + Invokes(testing.NewUpdateAction(limitrangesResource, c.ns, limitRange), &v1.LimitRange{}) if obj == nil { return nil, err } - return obj.(*corev1.LimitRange), err + return obj.(*v1.LimitRange), err } // Delete takes name of the limitRange and deletes it. Returns an error if one occurs. -func (c *FakeLimitRanges) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeLimitRanges) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(limitrangesResource, c.ns, name, opts), &corev1.LimitRange{}) + Invokes(testing.NewDeleteActionWithOptions(limitrangesResource, c.ns, name, opts), &v1.LimitRange{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeLimitRanges) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeLimitRanges) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(limitrangesResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &corev1.LimitRangeList{}) + _, err := c.Fake.Invokes(action, &v1.LimitRangeList{}) return err } // Patch applies the patch and returns the patched limitRange. -func (c *FakeLimitRanges) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.LimitRange, err error) { +func (c *FakeLimitRanges) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.LimitRange, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(limitrangesResource, c.ns, name, pt, data, subresources...), &corev1.LimitRange{}) + Invokes(testing.NewPatchSubresourceAction(limitrangesResource, c.ns, name, pt, data, subresources...), &v1.LimitRange{}) if obj == nil { return nil, err } - return obj.(*corev1.LimitRange), err + return obj.(*v1.LimitRange), err } // Apply takes the given apply declarative configuration, applies it and returns the applied limitRange. -func (c *FakeLimitRanges) Apply(ctx context.Context, limitRange *applyconfigurationscorev1.LimitRangeApplyConfiguration, opts v1.ApplyOptions) (result *corev1.LimitRange, err error) { +func (c *FakeLimitRanges) Apply(ctx context.Context, limitRange *corev1.LimitRangeApplyConfiguration, opts metav1.ApplyOptions) (result *v1.LimitRange, err error) { if limitRange == nil { return nil, fmt.Errorf("limitRange provided to Apply must not be nil") } @@ -146,10 +145,10 @@ func (c *FakeLimitRanges) Apply(ctx context.Context, limitRange *applyconfigurat return nil, fmt.Errorf("limitRange.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(limitrangesResource, c.ns, *name, types.ApplyPatchType, data), &corev1.LimitRange{}) + Invokes(testing.NewPatchSubresourceAction(limitrangesResource, c.ns, *name, types.ApplyPatchType, data), &v1.LimitRange{}) if obj == nil { return nil, err } - return obj.(*corev1.LimitRange), err + return obj.(*v1.LimitRange), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_namespace.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_namespace.go index 83ada9f723..52fcff591e 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_namespace.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_namespace.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakeNamespaces struct { Fake *FakeCoreV1 } -var namespacesResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "namespaces"} +var namespacesResource = v1.SchemeGroupVersion.WithResource("namespaces") -var namespacesKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Namespace"} +var namespacesKind = v1.SchemeGroupVersion.WithKind("Namespace") // Get takes name of the namespace, and returns the corresponding namespace object, and an error if there is any. -func (c *FakeNamespaces) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.Namespace, err error) { +func (c *FakeNamespaces) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Namespace, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(namespacesResource, name), &corev1.Namespace{}) + Invokes(testing.NewRootGetAction(namespacesResource, name), &v1.Namespace{}) if obj == nil { return nil, err } - return obj.(*corev1.Namespace), err + return obj.(*v1.Namespace), err } // List takes label and field selectors, and returns the list of Namespaces that match those selectors. -func (c *FakeNamespaces) List(ctx context.Context, opts v1.ListOptions) (result *corev1.NamespaceList, err error) { +func (c *FakeNamespaces) List(ctx context.Context, opts metav1.ListOptions) (result *v1.NamespaceList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(namespacesResource, namespacesKind, opts), &corev1.NamespaceList{}) + Invokes(testing.NewRootListAction(namespacesResource, namespacesKind, opts), &v1.NamespaceList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakeNamespaces) List(ctx context.Context, opts v1.ListOptions) (result if label == nil { label = labels.Everything() } - list := &corev1.NamespaceList{ListMeta: obj.(*corev1.NamespaceList).ListMeta} - for _, item := range obj.(*corev1.NamespaceList).Items { + list := &v1.NamespaceList{ListMeta: obj.(*v1.NamespaceList).ListMeta} + for _, item := range obj.(*v1.NamespaceList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,61 +73,61 @@ func (c *FakeNamespaces) List(ctx context.Context, opts v1.ListOptions) (result } // Watch returns a watch.Interface that watches the requested namespaces. -func (c *FakeNamespaces) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeNamespaces) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(namespacesResource, opts)) } // Create takes the representation of a namespace and creates it. Returns the server's representation of the namespace, and an error, if there is any. -func (c *FakeNamespaces) Create(ctx context.Context, namespace *corev1.Namespace, opts v1.CreateOptions) (result *corev1.Namespace, err error) { +func (c *FakeNamespaces) Create(ctx context.Context, namespace *v1.Namespace, opts metav1.CreateOptions) (result *v1.Namespace, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(namespacesResource, namespace), &corev1.Namespace{}) + Invokes(testing.NewRootCreateAction(namespacesResource, namespace), &v1.Namespace{}) if obj == nil { return nil, err } - return obj.(*corev1.Namespace), err + return obj.(*v1.Namespace), err } // Update takes the representation of a namespace and updates it. Returns the server's representation of the namespace, and an error, if there is any. -func (c *FakeNamespaces) Update(ctx context.Context, namespace *corev1.Namespace, opts v1.UpdateOptions) (result *corev1.Namespace, err error) { +func (c *FakeNamespaces) Update(ctx context.Context, namespace *v1.Namespace, opts metav1.UpdateOptions) (result *v1.Namespace, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(namespacesResource, namespace), &corev1.Namespace{}) + Invokes(testing.NewRootUpdateAction(namespacesResource, namespace), &v1.Namespace{}) if obj == nil { return nil, err } - return obj.(*corev1.Namespace), err + return obj.(*v1.Namespace), 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 *FakeNamespaces) UpdateStatus(ctx context.Context, namespace *corev1.Namespace, opts v1.UpdateOptions) (*corev1.Namespace, error) { +func (c *FakeNamespaces) UpdateStatus(ctx context.Context, namespace *v1.Namespace, opts metav1.UpdateOptions) (*v1.Namespace, error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateSubresourceAction(namespacesResource, "status", namespace), &corev1.Namespace{}) + Invokes(testing.NewRootUpdateSubresourceAction(namespacesResource, "status", namespace), &v1.Namespace{}) if obj == nil { return nil, err } - return obj.(*corev1.Namespace), err + return obj.(*v1.Namespace), err } // Delete takes name of the namespace and deletes it. Returns an error if one occurs. -func (c *FakeNamespaces) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeNamespaces) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(namespacesResource, name, opts), &corev1.Namespace{}) + Invokes(testing.NewRootDeleteActionWithOptions(namespacesResource, name, opts), &v1.Namespace{}) return err } // Patch applies the patch and returns the patched namespace. -func (c *FakeNamespaces) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.Namespace, err error) { +func (c *FakeNamespaces) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Namespace, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(namespacesResource, name, pt, data, subresources...), &corev1.Namespace{}) + Invokes(testing.NewRootPatchSubresourceAction(namespacesResource, name, pt, data, subresources...), &v1.Namespace{}) if obj == nil { return nil, err } - return obj.(*corev1.Namespace), err + return obj.(*v1.Namespace), err } // Apply takes the given apply declarative configuration, applies it and returns the applied namespace. -func (c *FakeNamespaces) Apply(ctx context.Context, namespace *applyconfigurationscorev1.NamespaceApplyConfiguration, opts v1.ApplyOptions) (result *corev1.Namespace, err error) { +func (c *FakeNamespaces) Apply(ctx context.Context, namespace *corev1.NamespaceApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Namespace, err error) { if namespace == nil { return nil, fmt.Errorf("namespace provided to Apply must not be nil") } @@ -141,16 +140,16 @@ func (c *FakeNamespaces) Apply(ctx context.Context, namespace *applyconfiguratio return nil, fmt.Errorf("namespace.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(namespacesResource, *name, types.ApplyPatchType, data), &corev1.Namespace{}) + Invokes(testing.NewRootPatchSubresourceAction(namespacesResource, *name, types.ApplyPatchType, data), &v1.Namespace{}) if obj == nil { return nil, err } - return obj.(*corev1.Namespace), err + return obj.(*v1.Namespace), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeNamespaces) ApplyStatus(ctx context.Context, namespace *applyconfigurationscorev1.NamespaceApplyConfiguration, opts v1.ApplyOptions) (result *corev1.Namespace, err error) { +func (c *FakeNamespaces) ApplyStatus(ctx context.Context, namespace *corev1.NamespaceApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Namespace, err error) { if namespace == nil { return nil, fmt.Errorf("namespace provided to Apply must not be nil") } @@ -163,9 +162,9 @@ func (c *FakeNamespaces) ApplyStatus(ctx context.Context, namespace *applyconfig return nil, fmt.Errorf("namespace.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(namespacesResource, *name, types.ApplyPatchType, data, "status"), &corev1.Namespace{}) + Invokes(testing.NewRootPatchSubresourceAction(namespacesResource, *name, types.ApplyPatchType, data, "status"), &v1.Namespace{}) if obj == nil { return nil, err } - return obj.(*corev1.Namespace), err + return obj.(*v1.Namespace), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_node.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_node.go index 82816deb44..5df40f8d11 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_node.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_node.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakeNodes struct { Fake *FakeCoreV1 } -var nodesResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "nodes"} +var nodesResource = v1.SchemeGroupVersion.WithResource("nodes") -var nodesKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Node"} +var nodesKind = v1.SchemeGroupVersion.WithKind("Node") // Get takes name of the node, and returns the corresponding node object, and an error if there is any. -func (c *FakeNodes) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.Node, err error) { +func (c *FakeNodes) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Node, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(nodesResource, name), &corev1.Node{}) + Invokes(testing.NewRootGetAction(nodesResource, name), &v1.Node{}) if obj == nil { return nil, err } - return obj.(*corev1.Node), err + return obj.(*v1.Node), err } // List takes label and field selectors, and returns the list of Nodes that match those selectors. -func (c *FakeNodes) List(ctx context.Context, opts v1.ListOptions) (result *corev1.NodeList, err error) { +func (c *FakeNodes) List(ctx context.Context, opts metav1.ListOptions) (result *v1.NodeList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(nodesResource, nodesKind, opts), &corev1.NodeList{}) + Invokes(testing.NewRootListAction(nodesResource, nodesKind, opts), &v1.NodeList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakeNodes) List(ctx context.Context, opts v1.ListOptions) (result *core if label == nil { label = labels.Everything() } - list := &corev1.NodeList{ListMeta: obj.(*corev1.NodeList).ListMeta} - for _, item := range obj.(*corev1.NodeList).Items { + list := &v1.NodeList{ListMeta: obj.(*v1.NodeList).ListMeta} + for _, item := range obj.(*v1.NodeList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,69 +73,69 @@ func (c *FakeNodes) List(ctx context.Context, opts v1.ListOptions) (result *core } // Watch returns a watch.Interface that watches the requested nodes. -func (c *FakeNodes) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeNodes) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(nodesResource, opts)) } // Create takes the representation of a node and creates it. Returns the server's representation of the node, and an error, if there is any. -func (c *FakeNodes) Create(ctx context.Context, node *corev1.Node, opts v1.CreateOptions) (result *corev1.Node, err error) { +func (c *FakeNodes) Create(ctx context.Context, node *v1.Node, opts metav1.CreateOptions) (result *v1.Node, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(nodesResource, node), &corev1.Node{}) + Invokes(testing.NewRootCreateAction(nodesResource, node), &v1.Node{}) if obj == nil { return nil, err } - return obj.(*corev1.Node), err + return obj.(*v1.Node), err } // Update takes the representation of a node and updates it. Returns the server's representation of the node, and an error, if there is any. -func (c *FakeNodes) Update(ctx context.Context, node *corev1.Node, opts v1.UpdateOptions) (result *corev1.Node, err error) { +func (c *FakeNodes) Update(ctx context.Context, node *v1.Node, opts metav1.UpdateOptions) (result *v1.Node, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(nodesResource, node), &corev1.Node{}) + Invokes(testing.NewRootUpdateAction(nodesResource, node), &v1.Node{}) if obj == nil { return nil, err } - return obj.(*corev1.Node), err + return obj.(*v1.Node), 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 *FakeNodes) UpdateStatus(ctx context.Context, node *corev1.Node, opts v1.UpdateOptions) (*corev1.Node, error) { +func (c *FakeNodes) UpdateStatus(ctx context.Context, node *v1.Node, opts metav1.UpdateOptions) (*v1.Node, error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateSubresourceAction(nodesResource, "status", node), &corev1.Node{}) + Invokes(testing.NewRootUpdateSubresourceAction(nodesResource, "status", node), &v1.Node{}) if obj == nil { return nil, err } - return obj.(*corev1.Node), err + return obj.(*v1.Node), err } // Delete takes name of the node and deletes it. Returns an error if one occurs. -func (c *FakeNodes) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeNodes) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(nodesResource, name, opts), &corev1.Node{}) + Invokes(testing.NewRootDeleteActionWithOptions(nodesResource, name, opts), &v1.Node{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeNodes) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeNodes) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(nodesResource, listOpts) - _, err := c.Fake.Invokes(action, &corev1.NodeList{}) + _, err := c.Fake.Invokes(action, &v1.NodeList{}) return err } // Patch applies the patch and returns the patched node. -func (c *FakeNodes) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.Node, err error) { +func (c *FakeNodes) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Node, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(nodesResource, name, pt, data, subresources...), &corev1.Node{}) + Invokes(testing.NewRootPatchSubresourceAction(nodesResource, name, pt, data, subresources...), &v1.Node{}) if obj == nil { return nil, err } - return obj.(*corev1.Node), err + return obj.(*v1.Node), err } // Apply takes the given apply declarative configuration, applies it and returns the applied node. -func (c *FakeNodes) Apply(ctx context.Context, node *applyconfigurationscorev1.NodeApplyConfiguration, opts v1.ApplyOptions) (result *corev1.Node, err error) { +func (c *FakeNodes) Apply(ctx context.Context, node *corev1.NodeApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Node, err error) { if node == nil { return nil, fmt.Errorf("node provided to Apply must not be nil") } @@ -149,16 +148,16 @@ func (c *FakeNodes) Apply(ctx context.Context, node *applyconfigurationscorev1.N return nil, fmt.Errorf("node.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(nodesResource, *name, types.ApplyPatchType, data), &corev1.Node{}) + Invokes(testing.NewRootPatchSubresourceAction(nodesResource, *name, types.ApplyPatchType, data), &v1.Node{}) if obj == nil { return nil, err } - return obj.(*corev1.Node), err + return obj.(*v1.Node), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeNodes) ApplyStatus(ctx context.Context, node *applyconfigurationscorev1.NodeApplyConfiguration, opts v1.ApplyOptions) (result *corev1.Node, err error) { +func (c *FakeNodes) ApplyStatus(ctx context.Context, node *corev1.NodeApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Node, err error) { if node == nil { return nil, fmt.Errorf("node provided to Apply must not be nil") } @@ -171,9 +170,9 @@ func (c *FakeNodes) ApplyStatus(ctx context.Context, node *applyconfigurationsco return nil, fmt.Errorf("node.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(nodesResource, *name, types.ApplyPatchType, data, "status"), &corev1.Node{}) + Invokes(testing.NewRootPatchSubresourceAction(nodesResource, *name, types.ApplyPatchType, data, "status"), &v1.Node{}) if obj == nil { return nil, err } - return obj.(*corev1.Node), err + return obj.(*v1.Node), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_persistentvolume.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_persistentvolume.go index d071a45dbb..5b06d0b192 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_persistentvolume.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_persistentvolume.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakePersistentVolumes struct { Fake *FakeCoreV1 } -var persistentvolumesResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "persistentvolumes"} +var persistentvolumesResource = v1.SchemeGroupVersion.WithResource("persistentvolumes") -var persistentvolumesKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "PersistentVolume"} +var persistentvolumesKind = v1.SchemeGroupVersion.WithKind("PersistentVolume") // Get takes name of the persistentVolume, and returns the corresponding persistentVolume object, and an error if there is any. -func (c *FakePersistentVolumes) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.PersistentVolume, err error) { +func (c *FakePersistentVolumes) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.PersistentVolume, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(persistentvolumesResource, name), &corev1.PersistentVolume{}) + Invokes(testing.NewRootGetAction(persistentvolumesResource, name), &v1.PersistentVolume{}) if obj == nil { return nil, err } - return obj.(*corev1.PersistentVolume), err + return obj.(*v1.PersistentVolume), err } // List takes label and field selectors, and returns the list of PersistentVolumes that match those selectors. -func (c *FakePersistentVolumes) List(ctx context.Context, opts v1.ListOptions) (result *corev1.PersistentVolumeList, err error) { +func (c *FakePersistentVolumes) List(ctx context.Context, opts metav1.ListOptions) (result *v1.PersistentVolumeList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(persistentvolumesResource, persistentvolumesKind, opts), &corev1.PersistentVolumeList{}) + Invokes(testing.NewRootListAction(persistentvolumesResource, persistentvolumesKind, opts), &v1.PersistentVolumeList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakePersistentVolumes) List(ctx context.Context, opts v1.ListOptions) ( if label == nil { label = labels.Everything() } - list := &corev1.PersistentVolumeList{ListMeta: obj.(*corev1.PersistentVolumeList).ListMeta} - for _, item := range obj.(*corev1.PersistentVolumeList).Items { + list := &v1.PersistentVolumeList{ListMeta: obj.(*v1.PersistentVolumeList).ListMeta} + for _, item := range obj.(*v1.PersistentVolumeList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,69 +73,69 @@ func (c *FakePersistentVolumes) List(ctx context.Context, opts v1.ListOptions) ( } // Watch returns a watch.Interface that watches the requested persistentVolumes. -func (c *FakePersistentVolumes) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakePersistentVolumes) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(persistentvolumesResource, opts)) } // Create takes the representation of a persistentVolume and creates it. Returns the server's representation of the persistentVolume, and an error, if there is any. -func (c *FakePersistentVolumes) Create(ctx context.Context, persistentVolume *corev1.PersistentVolume, opts v1.CreateOptions) (result *corev1.PersistentVolume, err error) { +func (c *FakePersistentVolumes) Create(ctx context.Context, persistentVolume *v1.PersistentVolume, opts metav1.CreateOptions) (result *v1.PersistentVolume, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(persistentvolumesResource, persistentVolume), &corev1.PersistentVolume{}) + Invokes(testing.NewRootCreateAction(persistentvolumesResource, persistentVolume), &v1.PersistentVolume{}) if obj == nil { return nil, err } - return obj.(*corev1.PersistentVolume), err + return obj.(*v1.PersistentVolume), err } // Update takes the representation of a persistentVolume and updates it. Returns the server's representation of the persistentVolume, and an error, if there is any. -func (c *FakePersistentVolumes) Update(ctx context.Context, persistentVolume *corev1.PersistentVolume, opts v1.UpdateOptions) (result *corev1.PersistentVolume, err error) { +func (c *FakePersistentVolumes) Update(ctx context.Context, persistentVolume *v1.PersistentVolume, opts metav1.UpdateOptions) (result *v1.PersistentVolume, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(persistentvolumesResource, persistentVolume), &corev1.PersistentVolume{}) + Invokes(testing.NewRootUpdateAction(persistentvolumesResource, persistentVolume), &v1.PersistentVolume{}) if obj == nil { return nil, err } - return obj.(*corev1.PersistentVolume), err + return obj.(*v1.PersistentVolume), 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 *FakePersistentVolumes) UpdateStatus(ctx context.Context, persistentVolume *corev1.PersistentVolume, opts v1.UpdateOptions) (*corev1.PersistentVolume, error) { +func (c *FakePersistentVolumes) UpdateStatus(ctx context.Context, persistentVolume *v1.PersistentVolume, opts metav1.UpdateOptions) (*v1.PersistentVolume, error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateSubresourceAction(persistentvolumesResource, "status", persistentVolume), &corev1.PersistentVolume{}) + Invokes(testing.NewRootUpdateSubresourceAction(persistentvolumesResource, "status", persistentVolume), &v1.PersistentVolume{}) if obj == nil { return nil, err } - return obj.(*corev1.PersistentVolume), err + return obj.(*v1.PersistentVolume), err } // Delete takes name of the persistentVolume and deletes it. Returns an error if one occurs. -func (c *FakePersistentVolumes) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakePersistentVolumes) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(persistentvolumesResource, name, opts), &corev1.PersistentVolume{}) + Invokes(testing.NewRootDeleteActionWithOptions(persistentvolumesResource, name, opts), &v1.PersistentVolume{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakePersistentVolumes) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakePersistentVolumes) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(persistentvolumesResource, listOpts) - _, err := c.Fake.Invokes(action, &corev1.PersistentVolumeList{}) + _, err := c.Fake.Invokes(action, &v1.PersistentVolumeList{}) return err } // Patch applies the patch and returns the patched persistentVolume. -func (c *FakePersistentVolumes) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.PersistentVolume, err error) { +func (c *FakePersistentVolumes) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.PersistentVolume, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(persistentvolumesResource, name, pt, data, subresources...), &corev1.PersistentVolume{}) + Invokes(testing.NewRootPatchSubresourceAction(persistentvolumesResource, name, pt, data, subresources...), &v1.PersistentVolume{}) if obj == nil { return nil, err } - return obj.(*corev1.PersistentVolume), err + return obj.(*v1.PersistentVolume), err } // Apply takes the given apply declarative configuration, applies it and returns the applied persistentVolume. -func (c *FakePersistentVolumes) Apply(ctx context.Context, persistentVolume *applyconfigurationscorev1.PersistentVolumeApplyConfiguration, opts v1.ApplyOptions) (result *corev1.PersistentVolume, err error) { +func (c *FakePersistentVolumes) Apply(ctx context.Context, persistentVolume *corev1.PersistentVolumeApplyConfiguration, opts metav1.ApplyOptions) (result *v1.PersistentVolume, err error) { if persistentVolume == nil { return nil, fmt.Errorf("persistentVolume provided to Apply must not be nil") } @@ -149,16 +148,16 @@ func (c *FakePersistentVolumes) Apply(ctx context.Context, persistentVolume *app return nil, fmt.Errorf("persistentVolume.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(persistentvolumesResource, *name, types.ApplyPatchType, data), &corev1.PersistentVolume{}) + Invokes(testing.NewRootPatchSubresourceAction(persistentvolumesResource, *name, types.ApplyPatchType, data), &v1.PersistentVolume{}) if obj == nil { return nil, err } - return obj.(*corev1.PersistentVolume), err + return obj.(*v1.PersistentVolume), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakePersistentVolumes) ApplyStatus(ctx context.Context, persistentVolume *applyconfigurationscorev1.PersistentVolumeApplyConfiguration, opts v1.ApplyOptions) (result *corev1.PersistentVolume, err error) { +func (c *FakePersistentVolumes) ApplyStatus(ctx context.Context, persistentVolume *corev1.PersistentVolumeApplyConfiguration, opts metav1.ApplyOptions) (result *v1.PersistentVolume, err error) { if persistentVolume == nil { return nil, fmt.Errorf("persistentVolume provided to Apply must not be nil") } @@ -171,9 +170,9 @@ func (c *FakePersistentVolumes) ApplyStatus(ctx context.Context, persistentVolum return nil, fmt.Errorf("persistentVolume.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(persistentvolumesResource, *name, types.ApplyPatchType, data, "status"), &corev1.PersistentVolume{}) + Invokes(testing.NewRootPatchSubresourceAction(persistentvolumesResource, *name, types.ApplyPatchType, data, "status"), &v1.PersistentVolume{}) if obj == nil { return nil, err } - return obj.(*corev1.PersistentVolume), err + return obj.(*v1.PersistentVolume), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_persistentvolumeclaim.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_persistentvolumeclaim.go index 6e4cef2602..b860e53674 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_persistentvolumeclaim.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_persistentvolumeclaim.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakePersistentVolumeClaims struct { ns string } -var persistentvolumeclaimsResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "persistentvolumeclaims"} +var persistentvolumeclaimsResource = v1.SchemeGroupVersion.WithResource("persistentvolumeclaims") -var persistentvolumeclaimsKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "PersistentVolumeClaim"} +var persistentvolumeclaimsKind = v1.SchemeGroupVersion.WithKind("PersistentVolumeClaim") // Get takes name of the persistentVolumeClaim, and returns the corresponding persistentVolumeClaim object, and an error if there is any. -func (c *FakePersistentVolumeClaims) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.PersistentVolumeClaim, err error) { +func (c *FakePersistentVolumeClaims) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.PersistentVolumeClaim, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(persistentvolumeclaimsResource, c.ns, name), &corev1.PersistentVolumeClaim{}) + Invokes(testing.NewGetAction(persistentvolumeclaimsResource, c.ns, name), &v1.PersistentVolumeClaim{}) if obj == nil { return nil, err } - return obj.(*corev1.PersistentVolumeClaim), err + return obj.(*v1.PersistentVolumeClaim), err } // List takes label and field selectors, and returns the list of PersistentVolumeClaims that match those selectors. -func (c *FakePersistentVolumeClaims) List(ctx context.Context, opts v1.ListOptions) (result *corev1.PersistentVolumeClaimList, err error) { +func (c *FakePersistentVolumeClaims) List(ctx context.Context, opts metav1.ListOptions) (result *v1.PersistentVolumeClaimList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(persistentvolumeclaimsResource, persistentvolumeclaimsKind, c.ns, opts), &corev1.PersistentVolumeClaimList{}) + Invokes(testing.NewListAction(persistentvolumeclaimsResource, persistentvolumeclaimsKind, c.ns, opts), &v1.PersistentVolumeClaimList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakePersistentVolumeClaims) List(ctx context.Context, opts v1.ListOptio if label == nil { label = labels.Everything() } - list := &corev1.PersistentVolumeClaimList{ListMeta: obj.(*corev1.PersistentVolumeClaimList).ListMeta} - for _, item := range obj.(*corev1.PersistentVolumeClaimList).Items { + list := &v1.PersistentVolumeClaimList{ListMeta: obj.(*v1.PersistentVolumeClaimList).ListMeta} + for _, item := range obj.(*v1.PersistentVolumeClaimList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,75 +76,75 @@ func (c *FakePersistentVolumeClaims) List(ctx context.Context, opts v1.ListOptio } // Watch returns a watch.Interface that watches the requested persistentVolumeClaims. -func (c *FakePersistentVolumeClaims) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakePersistentVolumeClaims) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(persistentvolumeclaimsResource, c.ns, opts)) } // Create takes the representation of a persistentVolumeClaim and creates it. Returns the server's representation of the persistentVolumeClaim, and an error, if there is any. -func (c *FakePersistentVolumeClaims) Create(ctx context.Context, persistentVolumeClaim *corev1.PersistentVolumeClaim, opts v1.CreateOptions) (result *corev1.PersistentVolumeClaim, err error) { +func (c *FakePersistentVolumeClaims) Create(ctx context.Context, persistentVolumeClaim *v1.PersistentVolumeClaim, opts metav1.CreateOptions) (result *v1.PersistentVolumeClaim, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(persistentvolumeclaimsResource, c.ns, persistentVolumeClaim), &corev1.PersistentVolumeClaim{}) + Invokes(testing.NewCreateAction(persistentvolumeclaimsResource, c.ns, persistentVolumeClaim), &v1.PersistentVolumeClaim{}) if obj == nil { return nil, err } - return obj.(*corev1.PersistentVolumeClaim), err + return obj.(*v1.PersistentVolumeClaim), err } // Update takes the representation of a persistentVolumeClaim and updates it. Returns the server's representation of the persistentVolumeClaim, and an error, if there is any. -func (c *FakePersistentVolumeClaims) Update(ctx context.Context, persistentVolumeClaim *corev1.PersistentVolumeClaim, opts v1.UpdateOptions) (result *corev1.PersistentVolumeClaim, err error) { +func (c *FakePersistentVolumeClaims) Update(ctx context.Context, persistentVolumeClaim *v1.PersistentVolumeClaim, opts metav1.UpdateOptions) (result *v1.PersistentVolumeClaim, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(persistentvolumeclaimsResource, c.ns, persistentVolumeClaim), &corev1.PersistentVolumeClaim{}) + Invokes(testing.NewUpdateAction(persistentvolumeclaimsResource, c.ns, persistentVolumeClaim), &v1.PersistentVolumeClaim{}) if obj == nil { return nil, err } - return obj.(*corev1.PersistentVolumeClaim), err + return obj.(*v1.PersistentVolumeClaim), 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 *FakePersistentVolumeClaims) UpdateStatus(ctx context.Context, persistentVolumeClaim *corev1.PersistentVolumeClaim, opts v1.UpdateOptions) (*corev1.PersistentVolumeClaim, error) { +func (c *FakePersistentVolumeClaims) UpdateStatus(ctx context.Context, persistentVolumeClaim *v1.PersistentVolumeClaim, opts metav1.UpdateOptions) (*v1.PersistentVolumeClaim, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(persistentvolumeclaimsResource, "status", c.ns, persistentVolumeClaim), &corev1.PersistentVolumeClaim{}) + Invokes(testing.NewUpdateSubresourceAction(persistentvolumeclaimsResource, "status", c.ns, persistentVolumeClaim), &v1.PersistentVolumeClaim{}) if obj == nil { return nil, err } - return obj.(*corev1.PersistentVolumeClaim), err + return obj.(*v1.PersistentVolumeClaim), err } // Delete takes name of the persistentVolumeClaim and deletes it. Returns an error if one occurs. -func (c *FakePersistentVolumeClaims) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakePersistentVolumeClaims) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(persistentvolumeclaimsResource, c.ns, name, opts), &corev1.PersistentVolumeClaim{}) + Invokes(testing.NewDeleteActionWithOptions(persistentvolumeclaimsResource, c.ns, name, opts), &v1.PersistentVolumeClaim{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakePersistentVolumeClaims) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakePersistentVolumeClaims) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(persistentvolumeclaimsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &corev1.PersistentVolumeClaimList{}) + _, err := c.Fake.Invokes(action, &v1.PersistentVolumeClaimList{}) return err } // Patch applies the patch and returns the patched persistentVolumeClaim. -func (c *FakePersistentVolumeClaims) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.PersistentVolumeClaim, err error) { +func (c *FakePersistentVolumeClaims) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.PersistentVolumeClaim, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(persistentvolumeclaimsResource, c.ns, name, pt, data, subresources...), &corev1.PersistentVolumeClaim{}) + Invokes(testing.NewPatchSubresourceAction(persistentvolumeclaimsResource, c.ns, name, pt, data, subresources...), &v1.PersistentVolumeClaim{}) if obj == nil { return nil, err } - return obj.(*corev1.PersistentVolumeClaim), err + return obj.(*v1.PersistentVolumeClaim), err } // Apply takes the given apply declarative configuration, applies it and returns the applied persistentVolumeClaim. -func (c *FakePersistentVolumeClaims) Apply(ctx context.Context, persistentVolumeClaim *applyconfigurationscorev1.PersistentVolumeClaimApplyConfiguration, opts v1.ApplyOptions) (result *corev1.PersistentVolumeClaim, err error) { +func (c *FakePersistentVolumeClaims) Apply(ctx context.Context, persistentVolumeClaim *corev1.PersistentVolumeClaimApplyConfiguration, opts metav1.ApplyOptions) (result *v1.PersistentVolumeClaim, err error) { if persistentVolumeClaim == nil { return nil, fmt.Errorf("persistentVolumeClaim provided to Apply must not be nil") } @@ -158,17 +157,17 @@ func (c *FakePersistentVolumeClaims) Apply(ctx context.Context, persistentVolume return nil, fmt.Errorf("persistentVolumeClaim.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(persistentvolumeclaimsResource, c.ns, *name, types.ApplyPatchType, data), &corev1.PersistentVolumeClaim{}) + Invokes(testing.NewPatchSubresourceAction(persistentvolumeclaimsResource, c.ns, *name, types.ApplyPatchType, data), &v1.PersistentVolumeClaim{}) if obj == nil { return nil, err } - return obj.(*corev1.PersistentVolumeClaim), err + return obj.(*v1.PersistentVolumeClaim), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakePersistentVolumeClaims) ApplyStatus(ctx context.Context, persistentVolumeClaim *applyconfigurationscorev1.PersistentVolumeClaimApplyConfiguration, opts v1.ApplyOptions) (result *corev1.PersistentVolumeClaim, err error) { +func (c *FakePersistentVolumeClaims) ApplyStatus(ctx context.Context, persistentVolumeClaim *corev1.PersistentVolumeClaimApplyConfiguration, opts metav1.ApplyOptions) (result *v1.PersistentVolumeClaim, err error) { if persistentVolumeClaim == nil { return nil, fmt.Errorf("persistentVolumeClaim provided to Apply must not be nil") } @@ -181,10 +180,10 @@ func (c *FakePersistentVolumeClaims) ApplyStatus(ctx context.Context, persistent return nil, fmt.Errorf("persistentVolumeClaim.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(persistentvolumeclaimsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &corev1.PersistentVolumeClaim{}) + Invokes(testing.NewPatchSubresourceAction(persistentvolumeclaimsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.PersistentVolumeClaim{}) if obj == nil { return nil, err } - return obj.(*corev1.PersistentVolumeClaim), err + return obj.(*v1.PersistentVolumeClaim), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_pod.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_pod.go index 38a1479550..23634c7d07 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_pod.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_pod.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakePods struct { ns string } -var podsResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"} +var podsResource = v1.SchemeGroupVersion.WithResource("pods") -var podsKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"} +var podsKind = v1.SchemeGroupVersion.WithKind("Pod") // Get takes name of the pod, and returns the corresponding pod object, and an error if there is any. -func (c *FakePods) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.Pod, err error) { +func (c *FakePods) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Pod, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(podsResource, c.ns, name), &corev1.Pod{}) + Invokes(testing.NewGetAction(podsResource, c.ns, name), &v1.Pod{}) if obj == nil { return nil, err } - return obj.(*corev1.Pod), err + return obj.(*v1.Pod), err } // List takes label and field selectors, and returns the list of Pods that match those selectors. -func (c *FakePods) List(ctx context.Context, opts v1.ListOptions) (result *corev1.PodList, err error) { +func (c *FakePods) List(ctx context.Context, opts metav1.ListOptions) (result *v1.PodList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(podsResource, podsKind, c.ns, opts), &corev1.PodList{}) + Invokes(testing.NewListAction(podsResource, podsKind, c.ns, opts), &v1.PodList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakePods) List(ctx context.Context, opts v1.ListOptions) (result *corev if label == nil { label = labels.Everything() } - list := &corev1.PodList{ListMeta: obj.(*corev1.PodList).ListMeta} - for _, item := range obj.(*corev1.PodList).Items { + list := &v1.PodList{ListMeta: obj.(*v1.PodList).ListMeta} + for _, item := range obj.(*v1.PodList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,75 +76,75 @@ func (c *FakePods) List(ctx context.Context, opts v1.ListOptions) (result *corev } // Watch returns a watch.Interface that watches the requested pods. -func (c *FakePods) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakePods) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(podsResource, c.ns, opts)) } // Create takes the representation of a pod and creates it. Returns the server's representation of the pod, and an error, if there is any. -func (c *FakePods) Create(ctx context.Context, pod *corev1.Pod, opts v1.CreateOptions) (result *corev1.Pod, err error) { +func (c *FakePods) Create(ctx context.Context, pod *v1.Pod, opts metav1.CreateOptions) (result *v1.Pod, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(podsResource, c.ns, pod), &corev1.Pod{}) + Invokes(testing.NewCreateAction(podsResource, c.ns, pod), &v1.Pod{}) if obj == nil { return nil, err } - return obj.(*corev1.Pod), err + return obj.(*v1.Pod), err } // Update takes the representation of a pod and updates it. Returns the server's representation of the pod, and an error, if there is any. -func (c *FakePods) Update(ctx context.Context, pod *corev1.Pod, opts v1.UpdateOptions) (result *corev1.Pod, err error) { +func (c *FakePods) Update(ctx context.Context, pod *v1.Pod, opts metav1.UpdateOptions) (result *v1.Pod, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(podsResource, c.ns, pod), &corev1.Pod{}) + Invokes(testing.NewUpdateAction(podsResource, c.ns, pod), &v1.Pod{}) if obj == nil { return nil, err } - return obj.(*corev1.Pod), err + return obj.(*v1.Pod), 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 *FakePods) UpdateStatus(ctx context.Context, pod *corev1.Pod, opts v1.UpdateOptions) (*corev1.Pod, error) { +func (c *FakePods) UpdateStatus(ctx context.Context, pod *v1.Pod, opts metav1.UpdateOptions) (*v1.Pod, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(podsResource, "status", c.ns, pod), &corev1.Pod{}) + Invokes(testing.NewUpdateSubresourceAction(podsResource, "status", c.ns, pod), &v1.Pod{}) if obj == nil { return nil, err } - return obj.(*corev1.Pod), err + return obj.(*v1.Pod), err } // Delete takes name of the pod and deletes it. Returns an error if one occurs. -func (c *FakePods) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakePods) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(podsResource, c.ns, name, opts), &corev1.Pod{}) + Invokes(testing.NewDeleteActionWithOptions(podsResource, c.ns, name, opts), &v1.Pod{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakePods) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakePods) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(podsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &corev1.PodList{}) + _, err := c.Fake.Invokes(action, &v1.PodList{}) return err } // Patch applies the patch and returns the patched pod. -func (c *FakePods) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.Pod, err error) { +func (c *FakePods) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Pod, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(podsResource, c.ns, name, pt, data, subresources...), &corev1.Pod{}) + Invokes(testing.NewPatchSubresourceAction(podsResource, c.ns, name, pt, data, subresources...), &v1.Pod{}) if obj == nil { return nil, err } - return obj.(*corev1.Pod), err + return obj.(*v1.Pod), err } // Apply takes the given apply declarative configuration, applies it and returns the applied pod. -func (c *FakePods) Apply(ctx context.Context, pod *applyconfigurationscorev1.PodApplyConfiguration, opts v1.ApplyOptions) (result *corev1.Pod, err error) { +func (c *FakePods) Apply(ctx context.Context, pod *corev1.PodApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Pod, err error) { if pod == nil { return nil, fmt.Errorf("pod provided to Apply must not be nil") } @@ -158,17 +157,17 @@ func (c *FakePods) Apply(ctx context.Context, pod *applyconfigurationscorev1.Pod return nil, fmt.Errorf("pod.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(podsResource, c.ns, *name, types.ApplyPatchType, data), &corev1.Pod{}) + Invokes(testing.NewPatchSubresourceAction(podsResource, c.ns, *name, types.ApplyPatchType, data), &v1.Pod{}) if obj == nil { return nil, err } - return obj.(*corev1.Pod), err + return obj.(*v1.Pod), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakePods) ApplyStatus(ctx context.Context, pod *applyconfigurationscorev1.PodApplyConfiguration, opts v1.ApplyOptions) (result *corev1.Pod, err error) { +func (c *FakePods) ApplyStatus(ctx context.Context, pod *corev1.PodApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Pod, err error) { if pod == nil { return nil, fmt.Errorf("pod provided to Apply must not be nil") } @@ -181,21 +180,21 @@ func (c *FakePods) ApplyStatus(ctx context.Context, pod *applyconfigurationscore return nil, fmt.Errorf("pod.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(podsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &corev1.Pod{}) + Invokes(testing.NewPatchSubresourceAction(podsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.Pod{}) if obj == nil { return nil, err } - return obj.(*corev1.Pod), err + return obj.(*v1.Pod), err } // UpdateEphemeralContainers takes the representation of a pod and updates it. Returns the server's representation of the pod, and an error, if there is any. -func (c *FakePods) UpdateEphemeralContainers(ctx context.Context, podName string, pod *corev1.Pod, opts v1.UpdateOptions) (result *corev1.Pod, err error) { +func (c *FakePods) UpdateEphemeralContainers(ctx context.Context, podName string, pod *v1.Pod, opts metav1.UpdateOptions) (result *v1.Pod, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(podsResource, "ephemeralcontainers", c.ns, pod), &corev1.Pod{}) + Invokes(testing.NewUpdateSubresourceAction(podsResource, "ephemeralcontainers", c.ns, pod), &v1.Pod{}) if obj == nil { return nil, err } - return obj.(*corev1.Pod), err + return obj.(*v1.Pod), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_podtemplate.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_podtemplate.go index 00711f36fb..9fa97ab402 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_podtemplate.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_podtemplate.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakePodTemplates struct { ns string } -var podtemplatesResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "podtemplates"} +var podtemplatesResource = v1.SchemeGroupVersion.WithResource("podtemplates") -var podtemplatesKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "PodTemplate"} +var podtemplatesKind = v1.SchemeGroupVersion.WithKind("PodTemplate") // Get takes name of the podTemplate, and returns the corresponding podTemplate object, and an error if there is any. -func (c *FakePodTemplates) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.PodTemplate, err error) { +func (c *FakePodTemplates) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.PodTemplate, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(podtemplatesResource, c.ns, name), &corev1.PodTemplate{}) + Invokes(testing.NewGetAction(podtemplatesResource, c.ns, name), &v1.PodTemplate{}) if obj == nil { return nil, err } - return obj.(*corev1.PodTemplate), err + return obj.(*v1.PodTemplate), err } // List takes label and field selectors, and returns the list of PodTemplates that match those selectors. -func (c *FakePodTemplates) List(ctx context.Context, opts v1.ListOptions) (result *corev1.PodTemplateList, err error) { +func (c *FakePodTemplates) List(ctx context.Context, opts metav1.ListOptions) (result *v1.PodTemplateList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(podtemplatesResource, podtemplatesKind, c.ns, opts), &corev1.PodTemplateList{}) + Invokes(testing.NewListAction(podtemplatesResource, podtemplatesKind, c.ns, opts), &v1.PodTemplateList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakePodTemplates) List(ctx context.Context, opts v1.ListOptions) (resul if label == nil { label = labels.Everything() } - list := &corev1.PodTemplateList{ListMeta: obj.(*corev1.PodTemplateList).ListMeta} - for _, item := range obj.(*corev1.PodTemplateList).Items { + list := &v1.PodTemplateList{ListMeta: obj.(*v1.PodTemplateList).ListMeta} + for _, item := range obj.(*v1.PodTemplateList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,63 +76,63 @@ func (c *FakePodTemplates) List(ctx context.Context, opts v1.ListOptions) (resul } // Watch returns a watch.Interface that watches the requested podTemplates. -func (c *FakePodTemplates) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakePodTemplates) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(podtemplatesResource, c.ns, opts)) } // Create takes the representation of a podTemplate and creates it. Returns the server's representation of the podTemplate, and an error, if there is any. -func (c *FakePodTemplates) Create(ctx context.Context, podTemplate *corev1.PodTemplate, opts v1.CreateOptions) (result *corev1.PodTemplate, err error) { +func (c *FakePodTemplates) Create(ctx context.Context, podTemplate *v1.PodTemplate, opts metav1.CreateOptions) (result *v1.PodTemplate, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(podtemplatesResource, c.ns, podTemplate), &corev1.PodTemplate{}) + Invokes(testing.NewCreateAction(podtemplatesResource, c.ns, podTemplate), &v1.PodTemplate{}) if obj == nil { return nil, err } - return obj.(*corev1.PodTemplate), err + return obj.(*v1.PodTemplate), err } // Update takes the representation of a podTemplate and updates it. Returns the server's representation of the podTemplate, and an error, if there is any. -func (c *FakePodTemplates) Update(ctx context.Context, podTemplate *corev1.PodTemplate, opts v1.UpdateOptions) (result *corev1.PodTemplate, err error) { +func (c *FakePodTemplates) Update(ctx context.Context, podTemplate *v1.PodTemplate, opts metav1.UpdateOptions) (result *v1.PodTemplate, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(podtemplatesResource, c.ns, podTemplate), &corev1.PodTemplate{}) + Invokes(testing.NewUpdateAction(podtemplatesResource, c.ns, podTemplate), &v1.PodTemplate{}) if obj == nil { return nil, err } - return obj.(*corev1.PodTemplate), err + return obj.(*v1.PodTemplate), err } // Delete takes name of the podTemplate and deletes it. Returns an error if one occurs. -func (c *FakePodTemplates) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakePodTemplates) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(podtemplatesResource, c.ns, name, opts), &corev1.PodTemplate{}) + Invokes(testing.NewDeleteActionWithOptions(podtemplatesResource, c.ns, name, opts), &v1.PodTemplate{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakePodTemplates) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakePodTemplates) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(podtemplatesResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &corev1.PodTemplateList{}) + _, err := c.Fake.Invokes(action, &v1.PodTemplateList{}) return err } // Patch applies the patch and returns the patched podTemplate. -func (c *FakePodTemplates) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.PodTemplate, err error) { +func (c *FakePodTemplates) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.PodTemplate, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(podtemplatesResource, c.ns, name, pt, data, subresources...), &corev1.PodTemplate{}) + Invokes(testing.NewPatchSubresourceAction(podtemplatesResource, c.ns, name, pt, data, subresources...), &v1.PodTemplate{}) if obj == nil { return nil, err } - return obj.(*corev1.PodTemplate), err + return obj.(*v1.PodTemplate), err } // Apply takes the given apply declarative configuration, applies it and returns the applied podTemplate. -func (c *FakePodTemplates) Apply(ctx context.Context, podTemplate *applyconfigurationscorev1.PodTemplateApplyConfiguration, opts v1.ApplyOptions) (result *corev1.PodTemplate, err error) { +func (c *FakePodTemplates) Apply(ctx context.Context, podTemplate *corev1.PodTemplateApplyConfiguration, opts metav1.ApplyOptions) (result *v1.PodTemplate, err error) { if podTemplate == nil { return nil, fmt.Errorf("podTemplate provided to Apply must not be nil") } @@ -146,10 +145,10 @@ func (c *FakePodTemplates) Apply(ctx context.Context, podTemplate *applyconfigur return nil, fmt.Errorf("podTemplate.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(podtemplatesResource, c.ns, *name, types.ApplyPatchType, data), &corev1.PodTemplate{}) + Invokes(testing.NewPatchSubresourceAction(podtemplatesResource, c.ns, *name, types.ApplyPatchType, data), &v1.PodTemplate{}) if obj == nil { return nil, err } - return obj.(*corev1.PodTemplate), err + return obj.(*v1.PodTemplate), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_replicationcontroller.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_replicationcontroller.go index 086f4dbf9f..1e469c9b1a 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_replicationcontroller.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_replicationcontroller.go @@ -24,13 +24,12 @@ import ( "fmt" autoscalingv1 "k8s.io/api/autoscaling/v1" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -40,25 +39,25 @@ type FakeReplicationControllers struct { ns string } -var replicationcontrollersResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "replicationcontrollers"} +var replicationcontrollersResource = v1.SchemeGroupVersion.WithResource("replicationcontrollers") -var replicationcontrollersKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "ReplicationController"} +var replicationcontrollersKind = v1.SchemeGroupVersion.WithKind("ReplicationController") // Get takes name of the replicationController, and returns the corresponding replicationController object, and an error if there is any. -func (c *FakeReplicationControllers) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.ReplicationController, err error) { +func (c *FakeReplicationControllers) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ReplicationController, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(replicationcontrollersResource, c.ns, name), &corev1.ReplicationController{}) + Invokes(testing.NewGetAction(replicationcontrollersResource, c.ns, name), &v1.ReplicationController{}) if obj == nil { return nil, err } - return obj.(*corev1.ReplicationController), err + return obj.(*v1.ReplicationController), err } // List takes label and field selectors, and returns the list of ReplicationControllers that match those selectors. -func (c *FakeReplicationControllers) List(ctx context.Context, opts v1.ListOptions) (result *corev1.ReplicationControllerList, err error) { +func (c *FakeReplicationControllers) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ReplicationControllerList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(replicationcontrollersResource, replicationcontrollersKind, c.ns, opts), &corev1.ReplicationControllerList{}) + Invokes(testing.NewListAction(replicationcontrollersResource, replicationcontrollersKind, c.ns, opts), &v1.ReplicationControllerList{}) if obj == nil { return nil, err @@ -68,8 +67,8 @@ func (c *FakeReplicationControllers) List(ctx context.Context, opts v1.ListOptio if label == nil { label = labels.Everything() } - list := &corev1.ReplicationControllerList{ListMeta: obj.(*corev1.ReplicationControllerList).ListMeta} - for _, item := range obj.(*corev1.ReplicationControllerList).Items { + list := &v1.ReplicationControllerList{ListMeta: obj.(*v1.ReplicationControllerList).ListMeta} + for _, item := range obj.(*v1.ReplicationControllerList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -78,75 +77,75 @@ func (c *FakeReplicationControllers) List(ctx context.Context, opts v1.ListOptio } // Watch returns a watch.Interface that watches the requested replicationControllers. -func (c *FakeReplicationControllers) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeReplicationControllers) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(replicationcontrollersResource, c.ns, opts)) } // Create takes the representation of a replicationController and creates it. Returns the server's representation of the replicationController, and an error, if there is any. -func (c *FakeReplicationControllers) Create(ctx context.Context, replicationController *corev1.ReplicationController, opts v1.CreateOptions) (result *corev1.ReplicationController, err error) { +func (c *FakeReplicationControllers) Create(ctx context.Context, replicationController *v1.ReplicationController, opts metav1.CreateOptions) (result *v1.ReplicationController, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(replicationcontrollersResource, c.ns, replicationController), &corev1.ReplicationController{}) + Invokes(testing.NewCreateAction(replicationcontrollersResource, c.ns, replicationController), &v1.ReplicationController{}) if obj == nil { return nil, err } - return obj.(*corev1.ReplicationController), err + return obj.(*v1.ReplicationController), err } // Update takes the representation of a replicationController and updates it. Returns the server's representation of the replicationController, and an error, if there is any. -func (c *FakeReplicationControllers) Update(ctx context.Context, replicationController *corev1.ReplicationController, opts v1.UpdateOptions) (result *corev1.ReplicationController, err error) { +func (c *FakeReplicationControllers) Update(ctx context.Context, replicationController *v1.ReplicationController, opts metav1.UpdateOptions) (result *v1.ReplicationController, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(replicationcontrollersResource, c.ns, replicationController), &corev1.ReplicationController{}) + Invokes(testing.NewUpdateAction(replicationcontrollersResource, c.ns, replicationController), &v1.ReplicationController{}) if obj == nil { return nil, err } - return obj.(*corev1.ReplicationController), err + return obj.(*v1.ReplicationController), 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 *FakeReplicationControllers) UpdateStatus(ctx context.Context, replicationController *corev1.ReplicationController, opts v1.UpdateOptions) (*corev1.ReplicationController, error) { +func (c *FakeReplicationControllers) UpdateStatus(ctx context.Context, replicationController *v1.ReplicationController, opts metav1.UpdateOptions) (*v1.ReplicationController, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(replicationcontrollersResource, "status", c.ns, replicationController), &corev1.ReplicationController{}) + Invokes(testing.NewUpdateSubresourceAction(replicationcontrollersResource, "status", c.ns, replicationController), &v1.ReplicationController{}) if obj == nil { return nil, err } - return obj.(*corev1.ReplicationController), err + return obj.(*v1.ReplicationController), err } // Delete takes name of the replicationController and deletes it. Returns an error if one occurs. -func (c *FakeReplicationControllers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeReplicationControllers) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(replicationcontrollersResource, c.ns, name, opts), &corev1.ReplicationController{}) + Invokes(testing.NewDeleteActionWithOptions(replicationcontrollersResource, c.ns, name, opts), &v1.ReplicationController{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeReplicationControllers) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeReplicationControllers) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(replicationcontrollersResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &corev1.ReplicationControllerList{}) + _, err := c.Fake.Invokes(action, &v1.ReplicationControllerList{}) return err } // Patch applies the patch and returns the patched replicationController. -func (c *FakeReplicationControllers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.ReplicationController, err error) { +func (c *FakeReplicationControllers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ReplicationController, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(replicationcontrollersResource, c.ns, name, pt, data, subresources...), &corev1.ReplicationController{}) + Invokes(testing.NewPatchSubresourceAction(replicationcontrollersResource, c.ns, name, pt, data, subresources...), &v1.ReplicationController{}) if obj == nil { return nil, err } - return obj.(*corev1.ReplicationController), err + return obj.(*v1.ReplicationController), err } // Apply takes the given apply declarative configuration, applies it and returns the applied replicationController. -func (c *FakeReplicationControllers) Apply(ctx context.Context, replicationController *applyconfigurationscorev1.ReplicationControllerApplyConfiguration, opts v1.ApplyOptions) (result *corev1.ReplicationController, err error) { +func (c *FakeReplicationControllers) Apply(ctx context.Context, replicationController *corev1.ReplicationControllerApplyConfiguration, opts metav1.ApplyOptions) (result *v1.ReplicationController, err error) { if replicationController == nil { return nil, fmt.Errorf("replicationController provided to Apply must not be nil") } @@ -159,17 +158,17 @@ func (c *FakeReplicationControllers) Apply(ctx context.Context, replicationContr return nil, fmt.Errorf("replicationController.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(replicationcontrollersResource, c.ns, *name, types.ApplyPatchType, data), &corev1.ReplicationController{}) + Invokes(testing.NewPatchSubresourceAction(replicationcontrollersResource, c.ns, *name, types.ApplyPatchType, data), &v1.ReplicationController{}) if obj == nil { return nil, err } - return obj.(*corev1.ReplicationController), err + return obj.(*v1.ReplicationController), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeReplicationControllers) ApplyStatus(ctx context.Context, replicationController *applyconfigurationscorev1.ReplicationControllerApplyConfiguration, opts v1.ApplyOptions) (result *corev1.ReplicationController, err error) { +func (c *FakeReplicationControllers) ApplyStatus(ctx context.Context, replicationController *corev1.ReplicationControllerApplyConfiguration, opts metav1.ApplyOptions) (result *v1.ReplicationController, err error) { if replicationController == nil { return nil, fmt.Errorf("replicationController provided to Apply must not be nil") } @@ -182,16 +181,16 @@ func (c *FakeReplicationControllers) ApplyStatus(ctx context.Context, replicatio return nil, fmt.Errorf("replicationController.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(replicationcontrollersResource, c.ns, *name, types.ApplyPatchType, data, "status"), &corev1.ReplicationController{}) + Invokes(testing.NewPatchSubresourceAction(replicationcontrollersResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.ReplicationController{}) if obj == nil { return nil, err } - return obj.(*corev1.ReplicationController), err + return obj.(*v1.ReplicationController), err } // GetScale takes name of the replicationController, and returns the corresponding scale object, and an error if there is any. -func (c *FakeReplicationControllers) GetScale(ctx context.Context, replicationControllerName string, options v1.GetOptions) (result *autoscalingv1.Scale, err error) { +func (c *FakeReplicationControllers) GetScale(ctx context.Context, replicationControllerName string, options metav1.GetOptions) (result *autoscalingv1.Scale, err error) { obj, err := c.Fake. Invokes(testing.NewGetSubresourceAction(replicationcontrollersResource, c.ns, "scale", replicationControllerName), &autoscalingv1.Scale{}) @@ -202,7 +201,7 @@ func (c *FakeReplicationControllers) GetScale(ctx context.Context, replicationCo } // 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(ctx context.Context, replicationControllerName string, scale *autoscalingv1.Scale, opts v1.UpdateOptions) (result *autoscalingv1.Scale, err error) { +func (c *FakeReplicationControllers) UpdateScale(ctx context.Context, replicationControllerName string, scale *autoscalingv1.Scale, opts metav1.UpdateOptions) (result *autoscalingv1.Scale, err error) { obj, err := c.Fake. Invokes(testing.NewUpdateSubresourceAction(replicationcontrollersResource, "scale", c.ns, scale), &autoscalingv1.Scale{}) diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_resourcequota.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_resourcequota.go index 9e008a9732..87664985ce 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_resourcequota.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_resourcequota.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeResourceQuotas struct { ns string } -var resourcequotasResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "resourcequotas"} +var resourcequotasResource = v1.SchemeGroupVersion.WithResource("resourcequotas") -var resourcequotasKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "ResourceQuota"} +var resourcequotasKind = v1.SchemeGroupVersion.WithKind("ResourceQuota") // Get takes name of the resourceQuota, and returns the corresponding resourceQuota object, and an error if there is any. -func (c *FakeResourceQuotas) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.ResourceQuota, err error) { +func (c *FakeResourceQuotas) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ResourceQuota, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(resourcequotasResource, c.ns, name), &corev1.ResourceQuota{}) + Invokes(testing.NewGetAction(resourcequotasResource, c.ns, name), &v1.ResourceQuota{}) if obj == nil { return nil, err } - return obj.(*corev1.ResourceQuota), err + return obj.(*v1.ResourceQuota), err } // List takes label and field selectors, and returns the list of ResourceQuotas that match those selectors. -func (c *FakeResourceQuotas) List(ctx context.Context, opts v1.ListOptions) (result *corev1.ResourceQuotaList, err error) { +func (c *FakeResourceQuotas) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ResourceQuotaList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(resourcequotasResource, resourcequotasKind, c.ns, opts), &corev1.ResourceQuotaList{}) + Invokes(testing.NewListAction(resourcequotasResource, resourcequotasKind, c.ns, opts), &v1.ResourceQuotaList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeResourceQuotas) List(ctx context.Context, opts v1.ListOptions) (res if label == nil { label = labels.Everything() } - list := &corev1.ResourceQuotaList{ListMeta: obj.(*corev1.ResourceQuotaList).ListMeta} - for _, item := range obj.(*corev1.ResourceQuotaList).Items { + list := &v1.ResourceQuotaList{ListMeta: obj.(*v1.ResourceQuotaList).ListMeta} + for _, item := range obj.(*v1.ResourceQuotaList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,75 +76,75 @@ func (c *FakeResourceQuotas) List(ctx context.Context, opts v1.ListOptions) (res } // Watch returns a watch.Interface that watches the requested resourceQuotas. -func (c *FakeResourceQuotas) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeResourceQuotas) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(resourcequotasResource, c.ns, opts)) } // Create takes the representation of a resourceQuota and creates it. Returns the server's representation of the resourceQuota, and an error, if there is any. -func (c *FakeResourceQuotas) Create(ctx context.Context, resourceQuota *corev1.ResourceQuota, opts v1.CreateOptions) (result *corev1.ResourceQuota, err error) { +func (c *FakeResourceQuotas) Create(ctx context.Context, resourceQuota *v1.ResourceQuota, opts metav1.CreateOptions) (result *v1.ResourceQuota, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(resourcequotasResource, c.ns, resourceQuota), &corev1.ResourceQuota{}) + Invokes(testing.NewCreateAction(resourcequotasResource, c.ns, resourceQuota), &v1.ResourceQuota{}) if obj == nil { return nil, err } - return obj.(*corev1.ResourceQuota), err + return obj.(*v1.ResourceQuota), err } // Update takes the representation of a resourceQuota and updates it. Returns the server's representation of the resourceQuota, and an error, if there is any. -func (c *FakeResourceQuotas) Update(ctx context.Context, resourceQuota *corev1.ResourceQuota, opts v1.UpdateOptions) (result *corev1.ResourceQuota, err error) { +func (c *FakeResourceQuotas) Update(ctx context.Context, resourceQuota *v1.ResourceQuota, opts metav1.UpdateOptions) (result *v1.ResourceQuota, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(resourcequotasResource, c.ns, resourceQuota), &corev1.ResourceQuota{}) + Invokes(testing.NewUpdateAction(resourcequotasResource, c.ns, resourceQuota), &v1.ResourceQuota{}) if obj == nil { return nil, err } - return obj.(*corev1.ResourceQuota), err + return obj.(*v1.ResourceQuota), 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 *FakeResourceQuotas) UpdateStatus(ctx context.Context, resourceQuota *corev1.ResourceQuota, opts v1.UpdateOptions) (*corev1.ResourceQuota, error) { +func (c *FakeResourceQuotas) UpdateStatus(ctx context.Context, resourceQuota *v1.ResourceQuota, opts metav1.UpdateOptions) (*v1.ResourceQuota, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(resourcequotasResource, "status", c.ns, resourceQuota), &corev1.ResourceQuota{}) + Invokes(testing.NewUpdateSubresourceAction(resourcequotasResource, "status", c.ns, resourceQuota), &v1.ResourceQuota{}) if obj == nil { return nil, err } - return obj.(*corev1.ResourceQuota), err + return obj.(*v1.ResourceQuota), err } // Delete takes name of the resourceQuota and deletes it. Returns an error if one occurs. -func (c *FakeResourceQuotas) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeResourceQuotas) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(resourcequotasResource, c.ns, name, opts), &corev1.ResourceQuota{}) + Invokes(testing.NewDeleteActionWithOptions(resourcequotasResource, c.ns, name, opts), &v1.ResourceQuota{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeResourceQuotas) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeResourceQuotas) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(resourcequotasResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &corev1.ResourceQuotaList{}) + _, err := c.Fake.Invokes(action, &v1.ResourceQuotaList{}) return err } // Patch applies the patch and returns the patched resourceQuota. -func (c *FakeResourceQuotas) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.ResourceQuota, err error) { +func (c *FakeResourceQuotas) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ResourceQuota, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(resourcequotasResource, c.ns, name, pt, data, subresources...), &corev1.ResourceQuota{}) + Invokes(testing.NewPatchSubresourceAction(resourcequotasResource, c.ns, name, pt, data, subresources...), &v1.ResourceQuota{}) if obj == nil { return nil, err } - return obj.(*corev1.ResourceQuota), err + return obj.(*v1.ResourceQuota), err } // Apply takes the given apply declarative configuration, applies it and returns the applied resourceQuota. -func (c *FakeResourceQuotas) Apply(ctx context.Context, resourceQuota *applyconfigurationscorev1.ResourceQuotaApplyConfiguration, opts v1.ApplyOptions) (result *corev1.ResourceQuota, err error) { +func (c *FakeResourceQuotas) Apply(ctx context.Context, resourceQuota *corev1.ResourceQuotaApplyConfiguration, opts metav1.ApplyOptions) (result *v1.ResourceQuota, err error) { if resourceQuota == nil { return nil, fmt.Errorf("resourceQuota provided to Apply must not be nil") } @@ -158,17 +157,17 @@ func (c *FakeResourceQuotas) Apply(ctx context.Context, resourceQuota *applyconf return nil, fmt.Errorf("resourceQuota.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(resourcequotasResource, c.ns, *name, types.ApplyPatchType, data), &corev1.ResourceQuota{}) + Invokes(testing.NewPatchSubresourceAction(resourcequotasResource, c.ns, *name, types.ApplyPatchType, data), &v1.ResourceQuota{}) if obj == nil { return nil, err } - return obj.(*corev1.ResourceQuota), err + return obj.(*v1.ResourceQuota), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeResourceQuotas) ApplyStatus(ctx context.Context, resourceQuota *applyconfigurationscorev1.ResourceQuotaApplyConfiguration, opts v1.ApplyOptions) (result *corev1.ResourceQuota, err error) { +func (c *FakeResourceQuotas) ApplyStatus(ctx context.Context, resourceQuota *corev1.ResourceQuotaApplyConfiguration, opts metav1.ApplyOptions) (result *v1.ResourceQuota, err error) { if resourceQuota == nil { return nil, fmt.Errorf("resourceQuota provided to Apply must not be nil") } @@ -181,10 +180,10 @@ func (c *FakeResourceQuotas) ApplyStatus(ctx context.Context, resourceQuota *app return nil, fmt.Errorf("resourceQuota.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(resourcequotasResource, c.ns, *name, types.ApplyPatchType, data, "status"), &corev1.ResourceQuota{}) + Invokes(testing.NewPatchSubresourceAction(resourcequotasResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.ResourceQuota{}) if obj == nil { return nil, err } - return obj.(*corev1.ResourceQuota), err + return obj.(*v1.ResourceQuota), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_secret.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_secret.go index b467305330..90035a7037 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_secret.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_secret.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeSecrets struct { ns string } -var secretsResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "secrets"} +var secretsResource = v1.SchemeGroupVersion.WithResource("secrets") -var secretsKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Secret"} +var secretsKind = v1.SchemeGroupVersion.WithKind("Secret") // Get takes name of the secret, and returns the corresponding secret object, and an error if there is any. -func (c *FakeSecrets) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.Secret, err error) { +func (c *FakeSecrets) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Secret, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(secretsResource, c.ns, name), &corev1.Secret{}) + Invokes(testing.NewGetAction(secretsResource, c.ns, name), &v1.Secret{}) if obj == nil { return nil, err } - return obj.(*corev1.Secret), err + return obj.(*v1.Secret), err } // List takes label and field selectors, and returns the list of Secrets that match those selectors. -func (c *FakeSecrets) List(ctx context.Context, opts v1.ListOptions) (result *corev1.SecretList, err error) { +func (c *FakeSecrets) List(ctx context.Context, opts metav1.ListOptions) (result *v1.SecretList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(secretsResource, secretsKind, c.ns, opts), &corev1.SecretList{}) + Invokes(testing.NewListAction(secretsResource, secretsKind, c.ns, opts), &v1.SecretList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeSecrets) List(ctx context.Context, opts v1.ListOptions) (result *co if label == nil { label = labels.Everything() } - list := &corev1.SecretList{ListMeta: obj.(*corev1.SecretList).ListMeta} - for _, item := range obj.(*corev1.SecretList).Items { + list := &v1.SecretList{ListMeta: obj.(*v1.SecretList).ListMeta} + for _, item := range obj.(*v1.SecretList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,63 +76,63 @@ func (c *FakeSecrets) List(ctx context.Context, opts v1.ListOptions) (result *co } // Watch returns a watch.Interface that watches the requested secrets. -func (c *FakeSecrets) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeSecrets) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(secretsResource, c.ns, opts)) } // Create takes the representation of a secret and creates it. Returns the server's representation of the secret, and an error, if there is any. -func (c *FakeSecrets) Create(ctx context.Context, secret *corev1.Secret, opts v1.CreateOptions) (result *corev1.Secret, err error) { +func (c *FakeSecrets) Create(ctx context.Context, secret *v1.Secret, opts metav1.CreateOptions) (result *v1.Secret, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(secretsResource, c.ns, secret), &corev1.Secret{}) + Invokes(testing.NewCreateAction(secretsResource, c.ns, secret), &v1.Secret{}) if obj == nil { return nil, err } - return obj.(*corev1.Secret), err + return obj.(*v1.Secret), err } // Update takes the representation of a secret and updates it. Returns the server's representation of the secret, and an error, if there is any. -func (c *FakeSecrets) Update(ctx context.Context, secret *corev1.Secret, opts v1.UpdateOptions) (result *corev1.Secret, err error) { +func (c *FakeSecrets) Update(ctx context.Context, secret *v1.Secret, opts metav1.UpdateOptions) (result *v1.Secret, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(secretsResource, c.ns, secret), &corev1.Secret{}) + Invokes(testing.NewUpdateAction(secretsResource, c.ns, secret), &v1.Secret{}) if obj == nil { return nil, err } - return obj.(*corev1.Secret), err + return obj.(*v1.Secret), err } // Delete takes name of the secret and deletes it. Returns an error if one occurs. -func (c *FakeSecrets) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeSecrets) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(secretsResource, c.ns, name, opts), &corev1.Secret{}) + Invokes(testing.NewDeleteActionWithOptions(secretsResource, c.ns, name, opts), &v1.Secret{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeSecrets) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeSecrets) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(secretsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &corev1.SecretList{}) + _, err := c.Fake.Invokes(action, &v1.SecretList{}) return err } // Patch applies the patch and returns the patched secret. -func (c *FakeSecrets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.Secret, err error) { +func (c *FakeSecrets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Secret, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(secretsResource, c.ns, name, pt, data, subresources...), &corev1.Secret{}) + Invokes(testing.NewPatchSubresourceAction(secretsResource, c.ns, name, pt, data, subresources...), &v1.Secret{}) if obj == nil { return nil, err } - return obj.(*corev1.Secret), err + return obj.(*v1.Secret), err } // Apply takes the given apply declarative configuration, applies it and returns the applied secret. -func (c *FakeSecrets) Apply(ctx context.Context, secret *applyconfigurationscorev1.SecretApplyConfiguration, opts v1.ApplyOptions) (result *corev1.Secret, err error) { +func (c *FakeSecrets) Apply(ctx context.Context, secret *corev1.SecretApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Secret, err error) { if secret == nil { return nil, fmt.Errorf("secret provided to Apply must not be nil") } @@ -146,10 +145,10 @@ func (c *FakeSecrets) Apply(ctx context.Context, secret *applyconfigurationscore return nil, fmt.Errorf("secret.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(secretsResource, c.ns, *name, types.ApplyPatchType, data), &corev1.Secret{}) + Invokes(testing.NewPatchSubresourceAction(secretsResource, c.ns, *name, types.ApplyPatchType, data), &v1.Secret{}) if obj == nil { return nil, err } - return obj.(*corev1.Secret), err + return obj.(*v1.Secret), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_service.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_service.go index bfbabec074..514ab19e39 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_service.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_service.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeServices struct { ns string } -var servicesResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "services"} +var servicesResource = v1.SchemeGroupVersion.WithResource("services") -var servicesKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Service"} +var servicesKind = v1.SchemeGroupVersion.WithKind("Service") // Get takes name of the service, and returns the corresponding service object, and an error if there is any. -func (c *FakeServices) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.Service, err error) { +func (c *FakeServices) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Service, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(servicesResource, c.ns, name), &corev1.Service{}) + Invokes(testing.NewGetAction(servicesResource, c.ns, name), &v1.Service{}) if obj == nil { return nil, err } - return obj.(*corev1.Service), err + return obj.(*v1.Service), err } // List takes label and field selectors, and returns the list of Services that match those selectors. -func (c *FakeServices) List(ctx context.Context, opts v1.ListOptions) (result *corev1.ServiceList, err error) { +func (c *FakeServices) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ServiceList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(servicesResource, servicesKind, c.ns, opts), &corev1.ServiceList{}) + Invokes(testing.NewListAction(servicesResource, servicesKind, c.ns, opts), &v1.ServiceList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeServices) List(ctx context.Context, opts v1.ListOptions) (result *c if label == nil { label = labels.Everything() } - list := &corev1.ServiceList{ListMeta: obj.(*corev1.ServiceList).ListMeta} - for _, item := range obj.(*corev1.ServiceList).Items { + list := &v1.ServiceList{ListMeta: obj.(*v1.ServiceList).ListMeta} + for _, item := range obj.(*v1.ServiceList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,67 +76,67 @@ func (c *FakeServices) List(ctx context.Context, opts v1.ListOptions) (result *c } // Watch returns a watch.Interface that watches the requested services. -func (c *FakeServices) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeServices) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(servicesResource, c.ns, opts)) } // Create takes the representation of a service and creates it. Returns the server's representation of the service, and an error, if there is any. -func (c *FakeServices) Create(ctx context.Context, service *corev1.Service, opts v1.CreateOptions) (result *corev1.Service, err error) { +func (c *FakeServices) Create(ctx context.Context, service *v1.Service, opts metav1.CreateOptions) (result *v1.Service, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(servicesResource, c.ns, service), &corev1.Service{}) + Invokes(testing.NewCreateAction(servicesResource, c.ns, service), &v1.Service{}) if obj == nil { return nil, err } - return obj.(*corev1.Service), err + return obj.(*v1.Service), err } // Update takes the representation of a service and updates it. Returns the server's representation of the service, and an error, if there is any. -func (c *FakeServices) Update(ctx context.Context, service *corev1.Service, opts v1.UpdateOptions) (result *corev1.Service, err error) { +func (c *FakeServices) Update(ctx context.Context, service *v1.Service, opts metav1.UpdateOptions) (result *v1.Service, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(servicesResource, c.ns, service), &corev1.Service{}) + Invokes(testing.NewUpdateAction(servicesResource, c.ns, service), &v1.Service{}) if obj == nil { return nil, err } - return obj.(*corev1.Service), err + return obj.(*v1.Service), 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 *FakeServices) UpdateStatus(ctx context.Context, service *corev1.Service, opts v1.UpdateOptions) (*corev1.Service, error) { +func (c *FakeServices) UpdateStatus(ctx context.Context, service *v1.Service, opts metav1.UpdateOptions) (*v1.Service, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(servicesResource, "status", c.ns, service), &corev1.Service{}) + Invokes(testing.NewUpdateSubresourceAction(servicesResource, "status", c.ns, service), &v1.Service{}) if obj == nil { return nil, err } - return obj.(*corev1.Service), err + return obj.(*v1.Service), err } // Delete takes name of the service and deletes it. Returns an error if one occurs. -func (c *FakeServices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeServices) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(servicesResource, c.ns, name, opts), &corev1.Service{}) + Invokes(testing.NewDeleteActionWithOptions(servicesResource, c.ns, name, opts), &v1.Service{}) return err } // Patch applies the patch and returns the patched service. -func (c *FakeServices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.Service, err error) { +func (c *FakeServices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Service, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(servicesResource, c.ns, name, pt, data, subresources...), &corev1.Service{}) + Invokes(testing.NewPatchSubresourceAction(servicesResource, c.ns, name, pt, data, subresources...), &v1.Service{}) if obj == nil { return nil, err } - return obj.(*corev1.Service), err + return obj.(*v1.Service), err } // Apply takes the given apply declarative configuration, applies it and returns the applied service. -func (c *FakeServices) Apply(ctx context.Context, service *applyconfigurationscorev1.ServiceApplyConfiguration, opts v1.ApplyOptions) (result *corev1.Service, err error) { +func (c *FakeServices) Apply(ctx context.Context, service *corev1.ServiceApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Service, err error) { if service == nil { return nil, fmt.Errorf("service provided to Apply must not be nil") } @@ -150,17 +149,17 @@ func (c *FakeServices) Apply(ctx context.Context, service *applyconfigurationsco return nil, fmt.Errorf("service.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(servicesResource, c.ns, *name, types.ApplyPatchType, data), &corev1.Service{}) + Invokes(testing.NewPatchSubresourceAction(servicesResource, c.ns, *name, types.ApplyPatchType, data), &v1.Service{}) if obj == nil { return nil, err } - return obj.(*corev1.Service), err + return obj.(*v1.Service), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeServices) ApplyStatus(ctx context.Context, service *applyconfigurationscorev1.ServiceApplyConfiguration, opts v1.ApplyOptions) (result *corev1.Service, err error) { +func (c *FakeServices) ApplyStatus(ctx context.Context, service *corev1.ServiceApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Service, err error) { if service == nil { return nil, fmt.Errorf("service provided to Apply must not be nil") } @@ -173,10 +172,10 @@ func (c *FakeServices) ApplyStatus(ctx context.Context, service *applyconfigurat return nil, fmt.Errorf("service.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(servicesResource, c.ns, *name, types.ApplyPatchType, data, "status"), &corev1.Service{}) + Invokes(testing.NewPatchSubresourceAction(servicesResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.Service{}) if obj == nil { return nil, err } - return obj.(*corev1.Service), err + return obj.(*v1.Service), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_serviceaccount.go b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_serviceaccount.go index ff468957a7..115ff07123 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_serviceaccount.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/core/v1/fake/fake_serviceaccount.go @@ -24,13 +24,12 @@ import ( "fmt" authenticationv1 "k8s.io/api/authentication/v1" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationscorev1 "k8s.io/client-go/applyconfigurations/core/v1" + corev1 "k8s.io/client-go/applyconfigurations/core/v1" testing "k8s.io/client-go/testing" ) @@ -40,25 +39,25 @@ type FakeServiceAccounts struct { ns string } -var serviceaccountsResource = schema.GroupVersionResource{Group: "", Version: "v1", Resource: "serviceaccounts"} +var serviceaccountsResource = v1.SchemeGroupVersion.WithResource("serviceaccounts") -var serviceaccountsKind = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "ServiceAccount"} +var serviceaccountsKind = v1.SchemeGroupVersion.WithKind("ServiceAccount") // Get takes name of the serviceAccount, and returns the corresponding serviceAccount object, and an error if there is any. -func (c *FakeServiceAccounts) Get(ctx context.Context, name string, options v1.GetOptions) (result *corev1.ServiceAccount, err error) { +func (c *FakeServiceAccounts) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ServiceAccount, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(serviceaccountsResource, c.ns, name), &corev1.ServiceAccount{}) + Invokes(testing.NewGetAction(serviceaccountsResource, c.ns, name), &v1.ServiceAccount{}) if obj == nil { return nil, err } - return obj.(*corev1.ServiceAccount), err + return obj.(*v1.ServiceAccount), err } // List takes label and field selectors, and returns the list of ServiceAccounts that match those selectors. -func (c *FakeServiceAccounts) List(ctx context.Context, opts v1.ListOptions) (result *corev1.ServiceAccountList, err error) { +func (c *FakeServiceAccounts) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ServiceAccountList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(serviceaccountsResource, serviceaccountsKind, c.ns, opts), &corev1.ServiceAccountList{}) + Invokes(testing.NewListAction(serviceaccountsResource, serviceaccountsKind, c.ns, opts), &v1.ServiceAccountList{}) if obj == nil { return nil, err @@ -68,8 +67,8 @@ func (c *FakeServiceAccounts) List(ctx context.Context, opts v1.ListOptions) (re if label == nil { label = labels.Everything() } - list := &corev1.ServiceAccountList{ListMeta: obj.(*corev1.ServiceAccountList).ListMeta} - for _, item := range obj.(*corev1.ServiceAccountList).Items { + list := &v1.ServiceAccountList{ListMeta: obj.(*v1.ServiceAccountList).ListMeta} + for _, item := range obj.(*v1.ServiceAccountList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -78,63 +77,63 @@ func (c *FakeServiceAccounts) List(ctx context.Context, opts v1.ListOptions) (re } // Watch returns a watch.Interface that watches the requested serviceAccounts. -func (c *FakeServiceAccounts) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeServiceAccounts) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(serviceaccountsResource, c.ns, opts)) } // Create takes the representation of a serviceAccount and creates it. Returns the server's representation of the serviceAccount, and an error, if there is any. -func (c *FakeServiceAccounts) Create(ctx context.Context, serviceAccount *corev1.ServiceAccount, opts v1.CreateOptions) (result *corev1.ServiceAccount, err error) { +func (c *FakeServiceAccounts) Create(ctx context.Context, serviceAccount *v1.ServiceAccount, opts metav1.CreateOptions) (result *v1.ServiceAccount, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(serviceaccountsResource, c.ns, serviceAccount), &corev1.ServiceAccount{}) + Invokes(testing.NewCreateAction(serviceaccountsResource, c.ns, serviceAccount), &v1.ServiceAccount{}) if obj == nil { return nil, err } - return obj.(*corev1.ServiceAccount), err + return obj.(*v1.ServiceAccount), err } // Update takes the representation of a serviceAccount and updates it. Returns the server's representation of the serviceAccount, and an error, if there is any. -func (c *FakeServiceAccounts) Update(ctx context.Context, serviceAccount *corev1.ServiceAccount, opts v1.UpdateOptions) (result *corev1.ServiceAccount, err error) { +func (c *FakeServiceAccounts) Update(ctx context.Context, serviceAccount *v1.ServiceAccount, opts metav1.UpdateOptions) (result *v1.ServiceAccount, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(serviceaccountsResource, c.ns, serviceAccount), &corev1.ServiceAccount{}) + Invokes(testing.NewUpdateAction(serviceaccountsResource, c.ns, serviceAccount), &v1.ServiceAccount{}) if obj == nil { return nil, err } - return obj.(*corev1.ServiceAccount), err + return obj.(*v1.ServiceAccount), err } // Delete takes name of the serviceAccount and deletes it. Returns an error if one occurs. -func (c *FakeServiceAccounts) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeServiceAccounts) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(serviceaccountsResource, c.ns, name, opts), &corev1.ServiceAccount{}) + Invokes(testing.NewDeleteActionWithOptions(serviceaccountsResource, c.ns, name, opts), &v1.ServiceAccount{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeServiceAccounts) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeServiceAccounts) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(serviceaccountsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &corev1.ServiceAccountList{}) + _, err := c.Fake.Invokes(action, &v1.ServiceAccountList{}) return err } // Patch applies the patch and returns the patched serviceAccount. -func (c *FakeServiceAccounts) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *corev1.ServiceAccount, err error) { +func (c *FakeServiceAccounts) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ServiceAccount, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(serviceaccountsResource, c.ns, name, pt, data, subresources...), &corev1.ServiceAccount{}) + Invokes(testing.NewPatchSubresourceAction(serviceaccountsResource, c.ns, name, pt, data, subresources...), &v1.ServiceAccount{}) if obj == nil { return nil, err } - return obj.(*corev1.ServiceAccount), err + return obj.(*v1.ServiceAccount), err } // Apply takes the given apply declarative configuration, applies it and returns the applied serviceAccount. -func (c *FakeServiceAccounts) Apply(ctx context.Context, serviceAccount *applyconfigurationscorev1.ServiceAccountApplyConfiguration, opts v1.ApplyOptions) (result *corev1.ServiceAccount, err error) { +func (c *FakeServiceAccounts) Apply(ctx context.Context, serviceAccount *corev1.ServiceAccountApplyConfiguration, opts metav1.ApplyOptions) (result *v1.ServiceAccount, err error) { if serviceAccount == nil { return nil, fmt.Errorf("serviceAccount provided to Apply must not be nil") } @@ -147,16 +146,16 @@ func (c *FakeServiceAccounts) Apply(ctx context.Context, serviceAccount *applyco return nil, fmt.Errorf("serviceAccount.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(serviceaccountsResource, c.ns, *name, types.ApplyPatchType, data), &corev1.ServiceAccount{}) + Invokes(testing.NewPatchSubresourceAction(serviceaccountsResource, c.ns, *name, types.ApplyPatchType, data), &v1.ServiceAccount{}) if obj == nil { return nil, err } - return obj.(*corev1.ServiceAccount), err + return obj.(*v1.ServiceAccount), err } // CreateToken takes the representation of a tokenRequest and creates it. Returns the server's representation of the tokenRequest, and an error, if there is any. -func (c *FakeServiceAccounts) CreateToken(ctx context.Context, serviceAccountName string, tokenRequest *authenticationv1.TokenRequest, opts v1.CreateOptions) (result *authenticationv1.TokenRequest, err error) { +func (c *FakeServiceAccounts) CreateToken(ctx context.Context, serviceAccountName string, tokenRequest *authenticationv1.TokenRequest, opts metav1.CreateOptions) (result *authenticationv1.TokenRequest, err error) { obj, err := c.Fake. Invokes(testing.NewCreateSubresourceAction(serviceaccountsResource, serviceAccountName, "token", c.ns, tokenRequest), &authenticationv1.TokenRequest{}) diff --git a/vendor/k8s.io/client-go/kubernetes/typed/discovery/v1/fake/fake_endpointslice.go b/vendor/k8s.io/client-go/kubernetes/typed/discovery/v1/fake/fake_endpointslice.go index 20e58b151f..d159b5ea9e 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/discovery/v1/fake/fake_endpointslice.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/discovery/v1/fake/fake_endpointslice.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - discoveryv1 "k8s.io/api/discovery/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/discovery/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsdiscoveryv1 "k8s.io/client-go/applyconfigurations/discovery/v1" + discoveryv1 "k8s.io/client-go/applyconfigurations/discovery/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeEndpointSlices struct { ns string } -var endpointslicesResource = schema.GroupVersionResource{Group: "discovery.k8s.io", Version: "v1", Resource: "endpointslices"} +var endpointslicesResource = v1.SchemeGroupVersion.WithResource("endpointslices") -var endpointslicesKind = schema.GroupVersionKind{Group: "discovery.k8s.io", Version: "v1", Kind: "EndpointSlice"} +var endpointslicesKind = v1.SchemeGroupVersion.WithKind("EndpointSlice") // Get takes name of the endpointSlice, and returns the corresponding endpointSlice object, and an error if there is any. -func (c *FakeEndpointSlices) Get(ctx context.Context, name string, options v1.GetOptions) (result *discoveryv1.EndpointSlice, err error) { +func (c *FakeEndpointSlices) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.EndpointSlice, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(endpointslicesResource, c.ns, name), &discoveryv1.EndpointSlice{}) + Invokes(testing.NewGetAction(endpointslicesResource, c.ns, name), &v1.EndpointSlice{}) if obj == nil { return nil, err } - return obj.(*discoveryv1.EndpointSlice), err + return obj.(*v1.EndpointSlice), err } // List takes label and field selectors, and returns the list of EndpointSlices that match those selectors. -func (c *FakeEndpointSlices) List(ctx context.Context, opts v1.ListOptions) (result *discoveryv1.EndpointSliceList, err error) { +func (c *FakeEndpointSlices) List(ctx context.Context, opts metav1.ListOptions) (result *v1.EndpointSliceList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(endpointslicesResource, endpointslicesKind, c.ns, opts), &discoveryv1.EndpointSliceList{}) + Invokes(testing.NewListAction(endpointslicesResource, endpointslicesKind, c.ns, opts), &v1.EndpointSliceList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeEndpointSlices) List(ctx context.Context, opts v1.ListOptions) (res if label == nil { label = labels.Everything() } - list := &discoveryv1.EndpointSliceList{ListMeta: obj.(*discoveryv1.EndpointSliceList).ListMeta} - for _, item := range obj.(*discoveryv1.EndpointSliceList).Items { + list := &v1.EndpointSliceList{ListMeta: obj.(*v1.EndpointSliceList).ListMeta} + for _, item := range obj.(*v1.EndpointSliceList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,63 +76,63 @@ func (c *FakeEndpointSlices) List(ctx context.Context, opts v1.ListOptions) (res } // Watch returns a watch.Interface that watches the requested endpointSlices. -func (c *FakeEndpointSlices) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeEndpointSlices) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(endpointslicesResource, c.ns, opts)) } // Create takes the representation of a endpointSlice and creates it. Returns the server's representation of the endpointSlice, and an error, if there is any. -func (c *FakeEndpointSlices) Create(ctx context.Context, endpointSlice *discoveryv1.EndpointSlice, opts v1.CreateOptions) (result *discoveryv1.EndpointSlice, err error) { +func (c *FakeEndpointSlices) Create(ctx context.Context, endpointSlice *v1.EndpointSlice, opts metav1.CreateOptions) (result *v1.EndpointSlice, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(endpointslicesResource, c.ns, endpointSlice), &discoveryv1.EndpointSlice{}) + Invokes(testing.NewCreateAction(endpointslicesResource, c.ns, endpointSlice), &v1.EndpointSlice{}) if obj == nil { return nil, err } - return obj.(*discoveryv1.EndpointSlice), err + return obj.(*v1.EndpointSlice), err } // Update takes the representation of a endpointSlice and updates it. Returns the server's representation of the endpointSlice, and an error, if there is any. -func (c *FakeEndpointSlices) Update(ctx context.Context, endpointSlice *discoveryv1.EndpointSlice, opts v1.UpdateOptions) (result *discoveryv1.EndpointSlice, err error) { +func (c *FakeEndpointSlices) Update(ctx context.Context, endpointSlice *v1.EndpointSlice, opts metav1.UpdateOptions) (result *v1.EndpointSlice, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(endpointslicesResource, c.ns, endpointSlice), &discoveryv1.EndpointSlice{}) + Invokes(testing.NewUpdateAction(endpointslicesResource, c.ns, endpointSlice), &v1.EndpointSlice{}) if obj == nil { return nil, err } - return obj.(*discoveryv1.EndpointSlice), err + return obj.(*v1.EndpointSlice), err } // Delete takes name of the endpointSlice and deletes it. Returns an error if one occurs. -func (c *FakeEndpointSlices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeEndpointSlices) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(endpointslicesResource, c.ns, name, opts), &discoveryv1.EndpointSlice{}) + Invokes(testing.NewDeleteActionWithOptions(endpointslicesResource, c.ns, name, opts), &v1.EndpointSlice{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeEndpointSlices) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeEndpointSlices) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(endpointslicesResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &discoveryv1.EndpointSliceList{}) + _, err := c.Fake.Invokes(action, &v1.EndpointSliceList{}) return err } // Patch applies the patch and returns the patched endpointSlice. -func (c *FakeEndpointSlices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *discoveryv1.EndpointSlice, err error) { +func (c *FakeEndpointSlices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.EndpointSlice, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(endpointslicesResource, c.ns, name, pt, data, subresources...), &discoveryv1.EndpointSlice{}) + Invokes(testing.NewPatchSubresourceAction(endpointslicesResource, c.ns, name, pt, data, subresources...), &v1.EndpointSlice{}) if obj == nil { return nil, err } - return obj.(*discoveryv1.EndpointSlice), err + return obj.(*v1.EndpointSlice), err } // Apply takes the given apply declarative configuration, applies it and returns the applied endpointSlice. -func (c *FakeEndpointSlices) Apply(ctx context.Context, endpointSlice *applyconfigurationsdiscoveryv1.EndpointSliceApplyConfiguration, opts v1.ApplyOptions) (result *discoveryv1.EndpointSlice, err error) { +func (c *FakeEndpointSlices) Apply(ctx context.Context, endpointSlice *discoveryv1.EndpointSliceApplyConfiguration, opts metav1.ApplyOptions) (result *v1.EndpointSlice, err error) { if endpointSlice == nil { return nil, fmt.Errorf("endpointSlice provided to Apply must not be nil") } @@ -146,10 +145,10 @@ func (c *FakeEndpointSlices) Apply(ctx context.Context, endpointSlice *applyconf return nil, fmt.Errorf("endpointSlice.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(endpointslicesResource, c.ns, *name, types.ApplyPatchType, data), &discoveryv1.EndpointSlice{}) + Invokes(testing.NewPatchSubresourceAction(endpointslicesResource, c.ns, *name, types.ApplyPatchType, data), &v1.EndpointSlice{}) if obj == nil { return nil, err } - return obj.(*discoveryv1.EndpointSlice), err + return obj.(*v1.EndpointSlice), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/discovery/v1beta1/fake/fake_endpointslice.go b/vendor/k8s.io/client-go/kubernetes/typed/discovery/v1beta1/fake/fake_endpointslice.go index 249de3446c..2683718113 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/discovery/v1beta1/fake/fake_endpointslice.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/discovery/v1beta1/fake/fake_endpointslice.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/discovery/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" discoveryv1beta1 "k8s.io/client-go/applyconfigurations/discovery/v1beta1" @@ -39,9 +38,9 @@ type FakeEndpointSlices struct { ns string } -var endpointslicesResource = schema.GroupVersionResource{Group: "discovery.k8s.io", Version: "v1beta1", Resource: "endpointslices"} +var endpointslicesResource = v1beta1.SchemeGroupVersion.WithResource("endpointslices") -var endpointslicesKind = schema.GroupVersionKind{Group: "discovery.k8s.io", Version: "v1beta1", Kind: "EndpointSlice"} +var endpointslicesKind = v1beta1.SchemeGroupVersion.WithKind("EndpointSlice") // Get takes name of the endpointSlice, and returns the corresponding endpointSlice object, and an error if there is any. func (c *FakeEndpointSlices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.EndpointSlice, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/events/v1/fake/fake_event.go b/vendor/k8s.io/client-go/kubernetes/typed/events/v1/fake/fake_event.go index 87ff13c822..0928781f1e 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/events/v1/fake/fake_event.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/events/v1/fake/fake_event.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - eventsv1 "k8s.io/api/events/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/events/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationseventsv1 "k8s.io/client-go/applyconfigurations/events/v1" + eventsv1 "k8s.io/client-go/applyconfigurations/events/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeEvents struct { ns string } -var eventsResource = schema.GroupVersionResource{Group: "events.k8s.io", Version: "v1", Resource: "events"} +var eventsResource = v1.SchemeGroupVersion.WithResource("events") -var eventsKind = schema.GroupVersionKind{Group: "events.k8s.io", Version: "v1", Kind: "Event"} +var eventsKind = v1.SchemeGroupVersion.WithKind("Event") // Get takes name of the event, and returns the corresponding event object, and an error if there is any. -func (c *FakeEvents) Get(ctx context.Context, name string, options v1.GetOptions) (result *eventsv1.Event, err error) { +func (c *FakeEvents) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Event, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(eventsResource, c.ns, name), &eventsv1.Event{}) + Invokes(testing.NewGetAction(eventsResource, c.ns, name), &v1.Event{}) if obj == nil { return nil, err } - return obj.(*eventsv1.Event), err + return obj.(*v1.Event), err } // List takes label and field selectors, and returns the list of Events that match those selectors. -func (c *FakeEvents) List(ctx context.Context, opts v1.ListOptions) (result *eventsv1.EventList, err error) { +func (c *FakeEvents) List(ctx context.Context, opts metav1.ListOptions) (result *v1.EventList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(eventsResource, eventsKind, c.ns, opts), &eventsv1.EventList{}) + Invokes(testing.NewListAction(eventsResource, eventsKind, c.ns, opts), &v1.EventList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeEvents) List(ctx context.Context, opts v1.ListOptions) (result *eve if label == nil { label = labels.Everything() } - list := &eventsv1.EventList{ListMeta: obj.(*eventsv1.EventList).ListMeta} - for _, item := range obj.(*eventsv1.EventList).Items { + list := &v1.EventList{ListMeta: obj.(*v1.EventList).ListMeta} + for _, item := range obj.(*v1.EventList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,63 +76,63 @@ func (c *FakeEvents) List(ctx context.Context, opts v1.ListOptions) (result *eve } // Watch returns a watch.Interface that watches the requested events. -func (c *FakeEvents) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeEvents) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(eventsResource, c.ns, opts)) } // Create takes the representation of a event and creates it. Returns the server's representation of the event, and an error, if there is any. -func (c *FakeEvents) Create(ctx context.Context, event *eventsv1.Event, opts v1.CreateOptions) (result *eventsv1.Event, err error) { +func (c *FakeEvents) Create(ctx context.Context, event *v1.Event, opts metav1.CreateOptions) (result *v1.Event, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(eventsResource, c.ns, event), &eventsv1.Event{}) + Invokes(testing.NewCreateAction(eventsResource, c.ns, event), &v1.Event{}) if obj == nil { return nil, err } - return obj.(*eventsv1.Event), err + return obj.(*v1.Event), err } // Update takes the representation of a event and updates it. Returns the server's representation of the event, and an error, if there is any. -func (c *FakeEvents) Update(ctx context.Context, event *eventsv1.Event, opts v1.UpdateOptions) (result *eventsv1.Event, err error) { +func (c *FakeEvents) Update(ctx context.Context, event *v1.Event, opts metav1.UpdateOptions) (result *v1.Event, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(eventsResource, c.ns, event), &eventsv1.Event{}) + Invokes(testing.NewUpdateAction(eventsResource, c.ns, event), &v1.Event{}) if obj == nil { return nil, err } - return obj.(*eventsv1.Event), err + return obj.(*v1.Event), err } // Delete takes name of the event and deletes it. Returns an error if one occurs. -func (c *FakeEvents) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeEvents) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(eventsResource, c.ns, name, opts), &eventsv1.Event{}) + Invokes(testing.NewDeleteActionWithOptions(eventsResource, c.ns, name, opts), &v1.Event{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeEvents) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeEvents) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(eventsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &eventsv1.EventList{}) + _, err := c.Fake.Invokes(action, &v1.EventList{}) return err } // Patch applies the patch and returns the patched event. -func (c *FakeEvents) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *eventsv1.Event, err error) { +func (c *FakeEvents) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Event, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(eventsResource, c.ns, name, pt, data, subresources...), &eventsv1.Event{}) + Invokes(testing.NewPatchSubresourceAction(eventsResource, c.ns, name, pt, data, subresources...), &v1.Event{}) if obj == nil { return nil, err } - return obj.(*eventsv1.Event), err + return obj.(*v1.Event), err } // Apply takes the given apply declarative configuration, applies it and returns the applied event. -func (c *FakeEvents) Apply(ctx context.Context, event *applyconfigurationseventsv1.EventApplyConfiguration, opts v1.ApplyOptions) (result *eventsv1.Event, err error) { +func (c *FakeEvents) Apply(ctx context.Context, event *eventsv1.EventApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Event, err error) { if event == nil { return nil, fmt.Errorf("event provided to Apply must not be nil") } @@ -146,10 +145,10 @@ func (c *FakeEvents) Apply(ctx context.Context, event *applyconfigurationsevents return nil, fmt.Errorf("event.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(eventsResource, c.ns, *name, types.ApplyPatchType, data), &eventsv1.Event{}) + Invokes(testing.NewPatchSubresourceAction(eventsResource, c.ns, *name, types.ApplyPatchType, data), &v1.Event{}) if obj == nil { return nil, err } - return obj.(*eventsv1.Event), err + return obj.(*v1.Event), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/event_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/event_expansion.go index 464fff9116..562f8d5e45 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/event_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/event_expansion.go @@ -82,8 +82,7 @@ func (e *events) UpdateWithEventNamespace(event *v1beta1.Event) (*v1beta1.Event, // It returns the copy of the event that the server returns, or an error. // The namespace and name of the target event is deduced from the event. // The namespace must either match this event client's namespace, or this event client must -// -// have been created with the "" namespace. +// have been created with the "" namespace. func (e *events) PatchWithEventNamespace(event *v1beta1.Event, data []byte) (*v1beta1.Event, error) { if e.ns != "" && event.Namespace != e.ns { return nil, fmt.Errorf("can't patch an event with namespace '%v' in namespace '%v'", event.Namespace, e.ns) diff --git a/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/fake/fake_event.go b/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/fake/fake_event.go index 5481c4d3f8..522b4dc063 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/fake/fake_event.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/fake/fake_event.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/events/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" eventsv1beta1 "k8s.io/client-go/applyconfigurations/events/v1beta1" @@ -39,9 +38,9 @@ type FakeEvents struct { ns string } -var eventsResource = schema.GroupVersionResource{Group: "events.k8s.io", Version: "v1beta1", Resource: "events"} +var eventsResource = v1beta1.SchemeGroupVersion.WithResource("events") -var eventsKind = schema.GroupVersionKind{Group: "events.k8s.io", Version: "v1beta1", Kind: "Event"} +var eventsKind = v1beta1.SchemeGroupVersion.WithKind("Event") // Get takes name of the event, and returns the corresponding event object, and an error if there is any. func (c *FakeEvents) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Event, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go index 827b514df6..4725d2cd16 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go @@ -32,7 +32,6 @@ type ExtensionsV1beta1Interface interface { DeploymentsGetter IngressesGetter NetworkPoliciesGetter - PodSecurityPoliciesGetter ReplicaSetsGetter } @@ -57,10 +56,6 @@ func (c *ExtensionsV1beta1Client) NetworkPolicies(namespace string) NetworkPolic return newNetworkPolicies(c, namespace) } -func (c *ExtensionsV1beta1Client) PodSecurityPolicies() PodSecurityPolicyInterface { - return newPodSecurityPolicies(c) -} - func (c *ExtensionsV1beta1Client) ReplicaSets(namespace string) ReplicaSetInterface { return newReplicaSets(c, namespace) } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_daemonset.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_daemonset.go index 11c05f1951..abe3d2da1f 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_daemonset.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_daemonset.go @@ -26,7 +26,6 @@ import ( 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" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" extensionsv1beta1 "k8s.io/client-go/applyconfigurations/extensions/v1beta1" @@ -39,9 +38,9 @@ type FakeDaemonSets struct { ns string } -var daemonsetsResource = schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "daemonsets"} +var daemonsetsResource = v1beta1.SchemeGroupVersion.WithResource("daemonsets") -var daemonsetsKind = schema.GroupVersionKind{Group: "extensions", Version: "v1beta1", Kind: "DaemonSet"} +var daemonsetsKind = v1beta1.SchemeGroupVersion.WithKind("DaemonSet") // Get takes name of the daemonSet, and returns the corresponding daemonSet object, and an error if there is any. func (c *FakeDaemonSets) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.DaemonSet, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_deployment.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_deployment.go index 9edf85d60e..e399361a92 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_deployment.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_deployment.go @@ -26,7 +26,6 @@ import ( 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" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" extensionsv1beta1 "k8s.io/client-go/applyconfigurations/extensions/v1beta1" @@ -39,9 +38,9 @@ type FakeDeployments struct { ns string } -var deploymentsResource = schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "deployments"} +var deploymentsResource = v1beta1.SchemeGroupVersion.WithResource("deployments") -var deploymentsKind = schema.GroupVersionKind{Group: "extensions", Version: "v1beta1", Kind: "Deployment"} +var deploymentsKind = v1beta1.SchemeGroupVersion.WithKind("Deployment") // Get takes name of the deployment, and returns the corresponding deployment object, and an error if there is any. func (c *FakeDeployments) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Deployment, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_extensions_client.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_extensions_client.go index 36c0d51bc3..a54c182eae 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_extensions_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_extensions_client.go @@ -44,10 +44,6 @@ func (c *FakeExtensionsV1beta1) NetworkPolicies(namespace string) v1beta1.Networ return &FakeNetworkPolicies{c, namespace} } -func (c *FakeExtensionsV1beta1) PodSecurityPolicies() v1beta1.PodSecurityPolicyInterface { - return &FakePodSecurityPolicies{c} -} - func (c *FakeExtensionsV1beta1) ReplicaSets(namespace string) v1beta1.ReplicaSetInterface { return &FakeReplicaSets{c, namespace} } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_ingress.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_ingress.go index d3bbd1abce..48ae51e80d 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_ingress.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_ingress.go @@ -26,7 +26,6 @@ import ( 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" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" extensionsv1beta1 "k8s.io/client-go/applyconfigurations/extensions/v1beta1" @@ -39,9 +38,9 @@ type FakeIngresses struct { ns string } -var ingressesResource = schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "ingresses"} +var ingressesResource = v1beta1.SchemeGroupVersion.WithResource("ingresses") -var ingressesKind = schema.GroupVersionKind{Group: "extensions", Version: "v1beta1", Kind: "Ingress"} +var ingressesKind = v1beta1.SchemeGroupVersion.WithKind("Ingress") // Get takes name of the ingress, and returns the corresponding ingress object, and an error if there is any. func (c *FakeIngresses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Ingress, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_networkpolicy.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_networkpolicy.go index 1ff5d8c992..7bf8c6972a 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_networkpolicy.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_networkpolicy.go @@ -26,7 +26,6 @@ import ( 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" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" extensionsv1beta1 "k8s.io/client-go/applyconfigurations/extensions/v1beta1" @@ -39,9 +38,9 @@ type FakeNetworkPolicies struct { ns string } -var networkpoliciesResource = schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "networkpolicies"} +var networkpoliciesResource = v1beta1.SchemeGroupVersion.WithResource("networkpolicies") -var networkpoliciesKind = schema.GroupVersionKind{Group: "extensions", Version: "v1beta1", Kind: "NetworkPolicy"} +var networkpoliciesKind = v1beta1.SchemeGroupVersion.WithKind("NetworkPolicy") // Get takes name of the networkPolicy, and returns the corresponding networkPolicy object, and an error if there is any. func (c *FakeNetworkPolicies) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.NetworkPolicy, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_podsecuritypolicy.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_podsecuritypolicy.go deleted file mode 100644 index dd53fd5bd7..0000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_podsecuritypolicy.go +++ /dev/null @@ -1,146 +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 - -import ( - "context" - json "encoding/json" - "fmt" - - 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" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - extensionsv1beta1 "k8s.io/client-go/applyconfigurations/extensions/v1beta1" - testing "k8s.io/client-go/testing" -) - -// FakePodSecurityPolicies implements PodSecurityPolicyInterface -type FakePodSecurityPolicies struct { - Fake *FakeExtensionsV1beta1 -} - -var podsecuritypoliciesResource = schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "podsecuritypolicies"} - -var podsecuritypoliciesKind = schema.GroupVersionKind{Group: "extensions", Version: "v1beta1", Kind: "PodSecurityPolicy"} - -// Get takes name of the podSecurityPolicy, and returns the corresponding podSecurityPolicy object, and an error if there is any. -func (c *FakePodSecurityPolicies) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.PodSecurityPolicy, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootGetAction(podsecuritypoliciesResource, name), &v1beta1.PodSecurityPolicy{}) - if obj == nil { - return nil, err - } - return obj.(*v1beta1.PodSecurityPolicy), err -} - -// List takes label and field selectors, and returns the list of PodSecurityPolicies that match those selectors. -func (c *FakePodSecurityPolicies) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.PodSecurityPolicyList, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootListAction(podsecuritypoliciesResource, podsecuritypoliciesKind, opts), &v1beta1.PodSecurityPolicyList{}) - if obj == nil { - return nil, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1beta1.PodSecurityPolicyList{ListMeta: obj.(*v1beta1.PodSecurityPolicyList).ListMeta} - for _, item := range obj.(*v1beta1.PodSecurityPolicyList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// Watch returns a watch.Interface that watches the requested podSecurityPolicies. -func (c *FakePodSecurityPolicies) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - return c.Fake. - InvokesWatch(testing.NewRootWatchAction(podsecuritypoliciesResource, opts)) -} - -// Create takes the representation of a podSecurityPolicy and creates it. Returns the server's representation of the podSecurityPolicy, and an error, if there is any. -func (c *FakePodSecurityPolicies) Create(ctx context.Context, podSecurityPolicy *v1beta1.PodSecurityPolicy, opts v1.CreateOptions) (result *v1beta1.PodSecurityPolicy, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(podsecuritypoliciesResource, podSecurityPolicy), &v1beta1.PodSecurityPolicy{}) - if obj == nil { - return nil, err - } - return obj.(*v1beta1.PodSecurityPolicy), err -} - -// Update takes the representation of a podSecurityPolicy and updates it. Returns the server's representation of the podSecurityPolicy, and an error, if there is any. -func (c *FakePodSecurityPolicies) Update(ctx context.Context, podSecurityPolicy *v1beta1.PodSecurityPolicy, opts v1.UpdateOptions) (result *v1beta1.PodSecurityPolicy, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(podsecuritypoliciesResource, podSecurityPolicy), &v1beta1.PodSecurityPolicy{}) - if obj == nil { - return nil, err - } - return obj.(*v1beta1.PodSecurityPolicy), err -} - -// Delete takes name of the podSecurityPolicy and deletes it. Returns an error if one occurs. -func (c *FakePodSecurityPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(podsecuritypoliciesResource, name, opts), &v1beta1.PodSecurityPolicy{}) - return err -} - -// DeleteCollection deletes a collection of objects. -func (c *FakePodSecurityPolicies) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewRootDeleteCollectionAction(podsecuritypoliciesResource, listOpts) - - _, err := c.Fake.Invokes(action, &v1beta1.PodSecurityPolicyList{}) - return err -} - -// Patch applies the patch and returns the patched podSecurityPolicy. -func (c *FakePodSecurityPolicies) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.PodSecurityPolicy, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(podsecuritypoliciesResource, name, pt, data, subresources...), &v1beta1.PodSecurityPolicy{}) - if obj == nil { - return nil, err - } - return obj.(*v1beta1.PodSecurityPolicy), err -} - -// Apply takes the given apply declarative configuration, applies it and returns the applied podSecurityPolicy. -func (c *FakePodSecurityPolicies) Apply(ctx context.Context, podSecurityPolicy *extensionsv1beta1.PodSecurityPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1beta1.PodSecurityPolicy, err error) { - if podSecurityPolicy == nil { - return nil, fmt.Errorf("podSecurityPolicy provided to Apply must not be nil") - } - data, err := json.Marshal(podSecurityPolicy) - if err != nil { - return nil, err - } - name := podSecurityPolicy.Name - if name == nil { - return nil, fmt.Errorf("podSecurityPolicy.Name must be provided to Apply") - } - obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(podsecuritypoliciesResource, *name, types.ApplyPatchType, data), &v1beta1.PodSecurityPolicy{}) - if obj == nil { - return nil, err - } - return obj.(*v1beta1.PodSecurityPolicy), err -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_replicaset.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_replicaset.go index d6d35e4938..42da6fa8b6 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_replicaset.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake/fake_replicaset.go @@ -26,7 +26,6 @@ import ( 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" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" extensionsv1beta1 "k8s.io/client-go/applyconfigurations/extensions/v1beta1" @@ -39,9 +38,9 @@ type FakeReplicaSets struct { ns string } -var replicasetsResource = schema.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "replicasets"} +var replicasetsResource = v1beta1.SchemeGroupVersion.WithResource("replicasets") -var replicasetsKind = schema.GroupVersionKind{Group: "extensions", Version: "v1beta1", Kind: "ReplicaSet"} +var replicasetsKind = v1beta1.SchemeGroupVersion.WithKind("ReplicaSet") // Get takes name of the replicaSet, and returns the corresponding replicaSet object, and an error if there is any. func (c *FakeReplicaSets) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ReplicaSet, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/generated_expansion.go index 41d28f0417..67fcf4992b 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/generated_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/generated_expansion.go @@ -24,6 +24,4 @@ type IngressExpansion interface{} type NetworkPolicyExpansion interface{} -type PodSecurityPolicyExpansion interface{} - type ReplicaSetExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/podsecuritypolicy.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/podsecuritypolicy.go deleted file mode 100644 index 3f38c3133d..0000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/podsecuritypolicy.go +++ /dev/null @@ -1,197 +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 ( - "context" - json "encoding/json" - "fmt" - "time" - - v1beta1 "k8s.io/api/extensions/v1beta1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - extensionsv1beta1 "k8s.io/client-go/applyconfigurations/extensions/v1beta1" - scheme "k8s.io/client-go/kubernetes/scheme" - rest "k8s.io/client-go/rest" -) - -// PodSecurityPoliciesGetter has a method to return a PodSecurityPolicyInterface. -// A group's client should implement this interface. -type PodSecurityPoliciesGetter interface { - PodSecurityPolicies() PodSecurityPolicyInterface -} - -// PodSecurityPolicyInterface has methods to work with PodSecurityPolicy resources. -type PodSecurityPolicyInterface interface { - Create(ctx context.Context, podSecurityPolicy *v1beta1.PodSecurityPolicy, opts v1.CreateOptions) (*v1beta1.PodSecurityPolicy, error) - Update(ctx context.Context, podSecurityPolicy *v1beta1.PodSecurityPolicy, opts v1.UpdateOptions) (*v1beta1.PodSecurityPolicy, error) - Delete(ctx context.Context, name string, opts v1.DeleteOptions) error - DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.PodSecurityPolicy, error) - List(ctx context.Context, opts v1.ListOptions) (*v1beta1.PodSecurityPolicyList, error) - Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.PodSecurityPolicy, err error) - Apply(ctx context.Context, podSecurityPolicy *extensionsv1beta1.PodSecurityPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1beta1.PodSecurityPolicy, err error) - PodSecurityPolicyExpansion -} - -// podSecurityPolicies implements PodSecurityPolicyInterface -type podSecurityPolicies struct { - client rest.Interface -} - -// newPodSecurityPolicies returns a PodSecurityPolicies -func newPodSecurityPolicies(c *ExtensionsV1beta1Client) *podSecurityPolicies { - return &podSecurityPolicies{ - client: c.RESTClient(), - } -} - -// Get takes name of the podSecurityPolicy, and returns the corresponding podSecurityPolicy object, and an error if there is any. -func (c *podSecurityPolicies) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.PodSecurityPolicy, err error) { - result = &v1beta1.PodSecurityPolicy{} - err = c.client.Get(). - Resource("podsecuritypolicies"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(ctx). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of PodSecurityPolicies that match those selectors. -func (c *podSecurityPolicies) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.PodSecurityPolicyList, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &v1beta1.PodSecurityPolicyList{} - err = c.client.Get(). - Resource("podsecuritypolicies"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Do(ctx). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested podSecurityPolicies. -func (c *podSecurityPolicies) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - Resource("podsecuritypolicies"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Watch(ctx) -} - -// Create takes the representation of a podSecurityPolicy and creates it. Returns the server's representation of the podSecurityPolicy, and an error, if there is any. -func (c *podSecurityPolicies) Create(ctx context.Context, podSecurityPolicy *v1beta1.PodSecurityPolicy, opts v1.CreateOptions) (result *v1beta1.PodSecurityPolicy, err error) { - result = &v1beta1.PodSecurityPolicy{} - err = c.client.Post(). - Resource("podsecuritypolicies"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(podSecurityPolicy). - Do(ctx). - Into(result) - return -} - -// Update takes the representation of a podSecurityPolicy and updates it. Returns the server's representation of the podSecurityPolicy, and an error, if there is any. -func (c *podSecurityPolicies) Update(ctx context.Context, podSecurityPolicy *v1beta1.PodSecurityPolicy, opts v1.UpdateOptions) (result *v1beta1.PodSecurityPolicy, err error) { - result = &v1beta1.PodSecurityPolicy{} - err = c.client.Put(). - Resource("podsecuritypolicies"). - Name(podSecurityPolicy.Name). - VersionedParams(&opts, scheme.ParameterCodec). - Body(podSecurityPolicy). - Do(ctx). - Into(result) - return -} - -// Delete takes name of the podSecurityPolicy and deletes it. Returns an error if one occurs. -func (c *podSecurityPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - return c.client.Delete(). - Resource("podsecuritypolicies"). - Name(name). - Body(&opts). - Do(ctx). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *podSecurityPolicies) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - var timeout time.Duration - if listOpts.TimeoutSeconds != nil { - timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - Resource("podsecuritypolicies"). - VersionedParams(&listOpts, scheme.ParameterCodec). - Timeout(timeout). - Body(&opts). - Do(ctx). - Error() -} - -// Patch applies the patch and returns the patched podSecurityPolicy. -func (c *podSecurityPolicies) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.PodSecurityPolicy, err error) { - result = &v1beta1.PodSecurityPolicy{} - err = c.client.Patch(pt). - Resource("podsecuritypolicies"). - Name(name). - SubResource(subresources...). - VersionedParams(&opts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} - -// Apply takes the given apply declarative configuration, applies it and returns the applied podSecurityPolicy. -func (c *podSecurityPolicies) Apply(ctx context.Context, podSecurityPolicy *extensionsv1beta1.PodSecurityPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1beta1.PodSecurityPolicy, err error) { - if podSecurityPolicy == nil { - return nil, fmt.Errorf("podSecurityPolicy provided to Apply must not be nil") - } - patchOpts := opts.ToPatchOptions() - data, err := json.Marshal(podSecurityPolicy) - if err != nil { - return nil, err - } - name := podSecurityPolicy.Name - if name == nil { - return nil, fmt.Errorf("podSecurityPolicy.Name must be provided to Apply") - } - result = &v1beta1.PodSecurityPolicy{} - err = c.client.Patch(types.ApplyPatchType). - Resource("podsecuritypolicies"). - Name(*name). - VersionedParams(&patchOpts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1/fake/fake_flowschema.go b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1/fake/fake_flowschema.go index 06730a1ea0..f367638892 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1/fake/fake_flowschema.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1/fake/fake_flowschema.go @@ -26,7 +26,6 @@ import ( v1alpha1 "k8s.io/api/flowcontrol/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" flowcontrolv1alpha1 "k8s.io/client-go/applyconfigurations/flowcontrol/v1alpha1" @@ -38,9 +37,9 @@ type FakeFlowSchemas struct { Fake *FakeFlowcontrolV1alpha1 } -var flowschemasResource = schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1alpha1", Resource: "flowschemas"} +var flowschemasResource = v1alpha1.SchemeGroupVersion.WithResource("flowschemas") -var flowschemasKind = schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1alpha1", Kind: "FlowSchema"} +var flowschemasKind = v1alpha1.SchemeGroupVersion.WithKind("FlowSchema") // Get takes name of the flowSchema, and returns the corresponding flowSchema object, and an error if there is any. func (c *FakeFlowSchemas) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.FlowSchema, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1/fake/fake_prioritylevelconfiguration.go b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1/fake/fake_prioritylevelconfiguration.go index 0e72282541..6512c36f69 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1/fake/fake_prioritylevelconfiguration.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1/fake/fake_prioritylevelconfiguration.go @@ -26,7 +26,6 @@ import ( v1alpha1 "k8s.io/api/flowcontrol/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" flowcontrolv1alpha1 "k8s.io/client-go/applyconfigurations/flowcontrol/v1alpha1" @@ -38,9 +37,9 @@ type FakePriorityLevelConfigurations struct { Fake *FakeFlowcontrolV1alpha1 } -var prioritylevelconfigurationsResource = schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1alpha1", Resource: "prioritylevelconfigurations"} +var prioritylevelconfigurationsResource = v1alpha1.SchemeGroupVersion.WithResource("prioritylevelconfigurations") -var prioritylevelconfigurationsKind = schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1alpha1", Kind: "PriorityLevelConfiguration"} +var prioritylevelconfigurationsKind = v1alpha1.SchemeGroupVersion.WithKind("PriorityLevelConfiguration") // Get takes name of the priorityLevelConfiguration, and returns the corresponding priorityLevelConfiguration object, and an error if there is any. func (c *FakePriorityLevelConfigurations) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.PriorityLevelConfiguration, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1/fake/fake_flowschema.go b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1/fake/fake_flowschema.go index 58d5ed14ef..be7a7e390f 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1/fake/fake_flowschema.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1/fake/fake_flowschema.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/flowcontrol/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" flowcontrolv1beta1 "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta1" @@ -38,9 +37,9 @@ type FakeFlowSchemas struct { Fake *FakeFlowcontrolV1beta1 } -var flowschemasResource = schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta1", Resource: "flowschemas"} +var flowschemasResource = v1beta1.SchemeGroupVersion.WithResource("flowschemas") -var flowschemasKind = schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta1", Kind: "FlowSchema"} +var flowschemasKind = v1beta1.SchemeGroupVersion.WithKind("FlowSchema") // Get takes name of the flowSchema, and returns the corresponding flowSchema object, and an error if there is any. func (c *FakeFlowSchemas) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.FlowSchema, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1/fake/fake_prioritylevelconfiguration.go b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1/fake/fake_prioritylevelconfiguration.go index 19fc62beb3..698a168b37 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1/fake/fake_prioritylevelconfiguration.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1/fake/fake_prioritylevelconfiguration.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/flowcontrol/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" flowcontrolv1beta1 "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta1" @@ -38,9 +37,9 @@ type FakePriorityLevelConfigurations struct { Fake *FakeFlowcontrolV1beta1 } -var prioritylevelconfigurationsResource = schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta1", Resource: "prioritylevelconfigurations"} +var prioritylevelconfigurationsResource = v1beta1.SchemeGroupVersion.WithResource("prioritylevelconfigurations") -var prioritylevelconfigurationsKind = schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta1", Kind: "PriorityLevelConfiguration"} +var prioritylevelconfigurationsKind = v1beta1.SchemeGroupVersion.WithKind("PriorityLevelConfiguration") // Get takes name of the priorityLevelConfiguration, and returns the corresponding priorityLevelConfiguration object, and an error if there is any. func (c *FakePriorityLevelConfigurations) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.PriorityLevelConfiguration, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2/fake/fake_flowschema.go b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2/fake/fake_flowschema.go index e4603eba71..7ce6d2116b 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2/fake/fake_flowschema.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2/fake/fake_flowschema.go @@ -26,7 +26,6 @@ import ( v1beta2 "k8s.io/api/flowcontrol/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" flowcontrolv1beta2 "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta2" @@ -38,9 +37,9 @@ type FakeFlowSchemas struct { Fake *FakeFlowcontrolV1beta2 } -var flowschemasResource = schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Resource: "flowschemas"} +var flowschemasResource = v1beta2.SchemeGroupVersion.WithResource("flowschemas") -var flowschemasKind = schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "FlowSchema"} +var flowschemasKind = v1beta2.SchemeGroupVersion.WithKind("FlowSchema") // Get takes name of the flowSchema, and returns the corresponding flowSchema object, and an error if there is any. func (c *FakeFlowSchemas) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.FlowSchema, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2/fake/fake_prioritylevelconfiguration.go b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2/fake/fake_prioritylevelconfiguration.go index e1979d0751..7340f8a09e 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2/fake/fake_prioritylevelconfiguration.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2/fake/fake_prioritylevelconfiguration.go @@ -26,7 +26,6 @@ import ( v1beta2 "k8s.io/api/flowcontrol/v1beta2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" flowcontrolv1beta2 "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta2" @@ -38,9 +37,9 @@ type FakePriorityLevelConfigurations struct { Fake *FakeFlowcontrolV1beta2 } -var prioritylevelconfigurationsResource = schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Resource: "prioritylevelconfigurations"} +var prioritylevelconfigurationsResource = v1beta2.SchemeGroupVersion.WithResource("prioritylevelconfigurations") -var prioritylevelconfigurationsKind = schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta2", Kind: "PriorityLevelConfiguration"} +var prioritylevelconfigurationsKind = v1beta2.SchemeGroupVersion.WithKind("PriorityLevelConfiguration") // Get takes name of the priorityLevelConfiguration, and returns the corresponding priorityLevelConfiguration object, and an error if there is any. func (c *FakePriorityLevelConfigurations) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.PriorityLevelConfiguration, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/fake/fake_flowschema.go b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/fake/fake_flowschema.go index d6a8bdc32f..1371f6ed67 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/fake/fake_flowschema.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/fake/fake_flowschema.go @@ -26,7 +26,6 @@ import ( v1beta3 "k8s.io/api/flowcontrol/v1beta3" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" flowcontrolv1beta3 "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3" @@ -38,9 +37,9 @@ type FakeFlowSchemas struct { Fake *FakeFlowcontrolV1beta3 } -var flowschemasResource = schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Resource: "flowschemas"} +var flowschemasResource = v1beta3.SchemeGroupVersion.WithResource("flowschemas") -var flowschemasKind = schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "FlowSchema"} +var flowschemasKind = v1beta3.SchemeGroupVersion.WithKind("FlowSchema") // Get takes name of the flowSchema, and returns the corresponding flowSchema object, and an error if there is any. func (c *FakeFlowSchemas) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta3.FlowSchema, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/fake/fake_prioritylevelconfiguration.go b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/fake/fake_prioritylevelconfiguration.go index 5fbc57da7f..a0e266fecb 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/fake/fake_prioritylevelconfiguration.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3/fake/fake_prioritylevelconfiguration.go @@ -26,7 +26,6 @@ import ( v1beta3 "k8s.io/api/flowcontrol/v1beta3" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" flowcontrolv1beta3 "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3" @@ -38,9 +37,9 @@ type FakePriorityLevelConfigurations struct { Fake *FakeFlowcontrolV1beta3 } -var prioritylevelconfigurationsResource = schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Resource: "prioritylevelconfigurations"} +var prioritylevelconfigurationsResource = v1beta3.SchemeGroupVersion.WithResource("prioritylevelconfigurations") -var prioritylevelconfigurationsKind = schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1beta3", Kind: "PriorityLevelConfiguration"} +var prioritylevelconfigurationsKind = v1beta3.SchemeGroupVersion.WithKind("PriorityLevelConfiguration") // Get takes name of the priorityLevelConfiguration, and returns the corresponding priorityLevelConfiguration object, and an error if there is any. func (c *FakePriorityLevelConfigurations) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta3.PriorityLevelConfiguration, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/fake/fake_ingress.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/fake/fake_ingress.go index 8ffcd7f97c..002de0dd8a 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/fake/fake_ingress.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/fake/fake_ingress.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - networkingv1 "k8s.io/api/networking/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsnetworkingv1 "k8s.io/client-go/applyconfigurations/networking/v1" + networkingv1 "k8s.io/client-go/applyconfigurations/networking/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeIngresses struct { ns string } -var ingressesResource = schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1", Resource: "ingresses"} +var ingressesResource = v1.SchemeGroupVersion.WithResource("ingresses") -var ingressesKind = schema.GroupVersionKind{Group: "networking.k8s.io", Version: "v1", Kind: "Ingress"} +var ingressesKind = v1.SchemeGroupVersion.WithKind("Ingress") // Get takes name of the ingress, and returns the corresponding ingress object, and an error if there is any. -func (c *FakeIngresses) Get(ctx context.Context, name string, options v1.GetOptions) (result *networkingv1.Ingress, err error) { +func (c *FakeIngresses) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Ingress, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(ingressesResource, c.ns, name), &networkingv1.Ingress{}) + Invokes(testing.NewGetAction(ingressesResource, c.ns, name), &v1.Ingress{}) if obj == nil { return nil, err } - return obj.(*networkingv1.Ingress), err + return obj.(*v1.Ingress), err } // List takes label and field selectors, and returns the list of Ingresses that match those selectors. -func (c *FakeIngresses) List(ctx context.Context, opts v1.ListOptions) (result *networkingv1.IngressList, err error) { +func (c *FakeIngresses) List(ctx context.Context, opts metav1.ListOptions) (result *v1.IngressList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(ingressesResource, ingressesKind, c.ns, opts), &networkingv1.IngressList{}) + Invokes(testing.NewListAction(ingressesResource, ingressesKind, c.ns, opts), &v1.IngressList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeIngresses) List(ctx context.Context, opts v1.ListOptions) (result * if label == nil { label = labels.Everything() } - list := &networkingv1.IngressList{ListMeta: obj.(*networkingv1.IngressList).ListMeta} - for _, item := range obj.(*networkingv1.IngressList).Items { + list := &v1.IngressList{ListMeta: obj.(*v1.IngressList).ListMeta} + for _, item := range obj.(*v1.IngressList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,75 +76,75 @@ func (c *FakeIngresses) List(ctx context.Context, opts v1.ListOptions) (result * } // Watch returns a watch.Interface that watches the requested ingresses. -func (c *FakeIngresses) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeIngresses) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(ingressesResource, c.ns, opts)) } // Create takes the representation of a ingress and creates it. Returns the server's representation of the ingress, and an error, if there is any. -func (c *FakeIngresses) Create(ctx context.Context, ingress *networkingv1.Ingress, opts v1.CreateOptions) (result *networkingv1.Ingress, err error) { +func (c *FakeIngresses) Create(ctx context.Context, ingress *v1.Ingress, opts metav1.CreateOptions) (result *v1.Ingress, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(ingressesResource, c.ns, ingress), &networkingv1.Ingress{}) + Invokes(testing.NewCreateAction(ingressesResource, c.ns, ingress), &v1.Ingress{}) if obj == nil { return nil, err } - return obj.(*networkingv1.Ingress), err + return obj.(*v1.Ingress), err } // Update takes the representation of a ingress and updates it. Returns the server's representation of the ingress, and an error, if there is any. -func (c *FakeIngresses) Update(ctx context.Context, ingress *networkingv1.Ingress, opts v1.UpdateOptions) (result *networkingv1.Ingress, err error) { +func (c *FakeIngresses) Update(ctx context.Context, ingress *v1.Ingress, opts metav1.UpdateOptions) (result *v1.Ingress, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(ingressesResource, c.ns, ingress), &networkingv1.Ingress{}) + Invokes(testing.NewUpdateAction(ingressesResource, c.ns, ingress), &v1.Ingress{}) if obj == nil { return nil, err } - return obj.(*networkingv1.Ingress), err + return obj.(*v1.Ingress), 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 *FakeIngresses) UpdateStatus(ctx context.Context, ingress *networkingv1.Ingress, opts v1.UpdateOptions) (*networkingv1.Ingress, error) { +func (c *FakeIngresses) UpdateStatus(ctx context.Context, ingress *v1.Ingress, opts metav1.UpdateOptions) (*v1.Ingress, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(ingressesResource, "status", c.ns, ingress), &networkingv1.Ingress{}) + Invokes(testing.NewUpdateSubresourceAction(ingressesResource, "status", c.ns, ingress), &v1.Ingress{}) if obj == nil { return nil, err } - return obj.(*networkingv1.Ingress), err + return obj.(*v1.Ingress), err } // Delete takes name of the ingress and deletes it. Returns an error if one occurs. -func (c *FakeIngresses) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeIngresses) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(ingressesResource, c.ns, name, opts), &networkingv1.Ingress{}) + Invokes(testing.NewDeleteActionWithOptions(ingressesResource, c.ns, name, opts), &v1.Ingress{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeIngresses) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeIngresses) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(ingressesResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &networkingv1.IngressList{}) + _, err := c.Fake.Invokes(action, &v1.IngressList{}) return err } // Patch applies the patch and returns the patched ingress. -func (c *FakeIngresses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *networkingv1.Ingress, err error) { +func (c *FakeIngresses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Ingress, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(ingressesResource, c.ns, name, pt, data, subresources...), &networkingv1.Ingress{}) + Invokes(testing.NewPatchSubresourceAction(ingressesResource, c.ns, name, pt, data, subresources...), &v1.Ingress{}) if obj == nil { return nil, err } - return obj.(*networkingv1.Ingress), err + return obj.(*v1.Ingress), err } // Apply takes the given apply declarative configuration, applies it and returns the applied ingress. -func (c *FakeIngresses) Apply(ctx context.Context, ingress *applyconfigurationsnetworkingv1.IngressApplyConfiguration, opts v1.ApplyOptions) (result *networkingv1.Ingress, err error) { +func (c *FakeIngresses) Apply(ctx context.Context, ingress *networkingv1.IngressApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Ingress, err error) { if ingress == nil { return nil, fmt.Errorf("ingress provided to Apply must not be nil") } @@ -158,17 +157,17 @@ func (c *FakeIngresses) Apply(ctx context.Context, ingress *applyconfigurationsn return nil, fmt.Errorf("ingress.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(ingressesResource, c.ns, *name, types.ApplyPatchType, data), &networkingv1.Ingress{}) + Invokes(testing.NewPatchSubresourceAction(ingressesResource, c.ns, *name, types.ApplyPatchType, data), &v1.Ingress{}) if obj == nil { return nil, err } - return obj.(*networkingv1.Ingress), err + return obj.(*v1.Ingress), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeIngresses) ApplyStatus(ctx context.Context, ingress *applyconfigurationsnetworkingv1.IngressApplyConfiguration, opts v1.ApplyOptions) (result *networkingv1.Ingress, err error) { +func (c *FakeIngresses) ApplyStatus(ctx context.Context, ingress *networkingv1.IngressApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Ingress, err error) { if ingress == nil { return nil, fmt.Errorf("ingress provided to Apply must not be nil") } @@ -181,10 +180,10 @@ func (c *FakeIngresses) ApplyStatus(ctx context.Context, ingress *applyconfigura return nil, fmt.Errorf("ingress.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(ingressesResource, c.ns, *name, types.ApplyPatchType, data, "status"), &networkingv1.Ingress{}) + Invokes(testing.NewPatchSubresourceAction(ingressesResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.Ingress{}) if obj == nil { return nil, err } - return obj.(*networkingv1.Ingress), err + return obj.(*v1.Ingress), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/fake/fake_ingressclass.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/fake/fake_ingressclass.go index fe320c4b72..208a975082 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/fake/fake_ingressclass.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/fake/fake_ingressclass.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - networkingv1 "k8s.io/api/networking/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsnetworkingv1 "k8s.io/client-go/applyconfigurations/networking/v1" + networkingv1 "k8s.io/client-go/applyconfigurations/networking/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakeIngressClasses struct { Fake *FakeNetworkingV1 } -var ingressclassesResource = schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1", Resource: "ingressclasses"} +var ingressclassesResource = v1.SchemeGroupVersion.WithResource("ingressclasses") -var ingressclassesKind = schema.GroupVersionKind{Group: "networking.k8s.io", Version: "v1", Kind: "IngressClass"} +var ingressclassesKind = v1.SchemeGroupVersion.WithKind("IngressClass") // Get takes name of the ingressClass, and returns the corresponding ingressClass object, and an error if there is any. -func (c *FakeIngressClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *networkingv1.IngressClass, err error) { +func (c *FakeIngressClasses) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.IngressClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(ingressclassesResource, name), &networkingv1.IngressClass{}) + Invokes(testing.NewRootGetAction(ingressclassesResource, name), &v1.IngressClass{}) if obj == nil { return nil, err } - return obj.(*networkingv1.IngressClass), err + return obj.(*v1.IngressClass), err } // List takes label and field selectors, and returns the list of IngressClasses that match those selectors. -func (c *FakeIngressClasses) List(ctx context.Context, opts v1.ListOptions) (result *networkingv1.IngressClassList, err error) { +func (c *FakeIngressClasses) List(ctx context.Context, opts metav1.ListOptions) (result *v1.IngressClassList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(ingressclassesResource, ingressclassesKind, opts), &networkingv1.IngressClassList{}) + Invokes(testing.NewRootListAction(ingressclassesResource, ingressclassesKind, opts), &v1.IngressClassList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakeIngressClasses) List(ctx context.Context, opts v1.ListOptions) (res if label == nil { label = labels.Everything() } - list := &networkingv1.IngressClassList{ListMeta: obj.(*networkingv1.IngressClassList).ListMeta} - for _, item := range obj.(*networkingv1.IngressClassList).Items { + list := &v1.IngressClassList{ListMeta: obj.(*v1.IngressClassList).ListMeta} + for _, item := range obj.(*v1.IngressClassList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,58 +73,58 @@ func (c *FakeIngressClasses) List(ctx context.Context, opts v1.ListOptions) (res } // Watch returns a watch.Interface that watches the requested ingressClasses. -func (c *FakeIngressClasses) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeIngressClasses) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(ingressclassesResource, opts)) } // Create takes the representation of a ingressClass and creates it. Returns the server's representation of the ingressClass, and an error, if there is any. -func (c *FakeIngressClasses) Create(ctx context.Context, ingressClass *networkingv1.IngressClass, opts v1.CreateOptions) (result *networkingv1.IngressClass, err error) { +func (c *FakeIngressClasses) Create(ctx context.Context, ingressClass *v1.IngressClass, opts metav1.CreateOptions) (result *v1.IngressClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(ingressclassesResource, ingressClass), &networkingv1.IngressClass{}) + Invokes(testing.NewRootCreateAction(ingressclassesResource, ingressClass), &v1.IngressClass{}) if obj == nil { return nil, err } - return obj.(*networkingv1.IngressClass), err + return obj.(*v1.IngressClass), err } // Update takes the representation of a ingressClass and updates it. Returns the server's representation of the ingressClass, and an error, if there is any. -func (c *FakeIngressClasses) Update(ctx context.Context, ingressClass *networkingv1.IngressClass, opts v1.UpdateOptions) (result *networkingv1.IngressClass, err error) { +func (c *FakeIngressClasses) Update(ctx context.Context, ingressClass *v1.IngressClass, opts metav1.UpdateOptions) (result *v1.IngressClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(ingressclassesResource, ingressClass), &networkingv1.IngressClass{}) + Invokes(testing.NewRootUpdateAction(ingressclassesResource, ingressClass), &v1.IngressClass{}) if obj == nil { return nil, err } - return obj.(*networkingv1.IngressClass), err + return obj.(*v1.IngressClass), err } // Delete takes name of the ingressClass and deletes it. Returns an error if one occurs. -func (c *FakeIngressClasses) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeIngressClasses) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(ingressclassesResource, name, opts), &networkingv1.IngressClass{}) + Invokes(testing.NewRootDeleteActionWithOptions(ingressclassesResource, name, opts), &v1.IngressClass{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeIngressClasses) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeIngressClasses) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(ingressclassesResource, listOpts) - _, err := c.Fake.Invokes(action, &networkingv1.IngressClassList{}) + _, err := c.Fake.Invokes(action, &v1.IngressClassList{}) return err } // Patch applies the patch and returns the patched ingressClass. -func (c *FakeIngressClasses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *networkingv1.IngressClass, err error) { +func (c *FakeIngressClasses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.IngressClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(ingressclassesResource, name, pt, data, subresources...), &networkingv1.IngressClass{}) + Invokes(testing.NewRootPatchSubresourceAction(ingressclassesResource, name, pt, data, subresources...), &v1.IngressClass{}) if obj == nil { return nil, err } - return obj.(*networkingv1.IngressClass), err + return obj.(*v1.IngressClass), err } // Apply takes the given apply declarative configuration, applies it and returns the applied ingressClass. -func (c *FakeIngressClasses) Apply(ctx context.Context, ingressClass *applyconfigurationsnetworkingv1.IngressClassApplyConfiguration, opts v1.ApplyOptions) (result *networkingv1.IngressClass, err error) { +func (c *FakeIngressClasses) Apply(ctx context.Context, ingressClass *networkingv1.IngressClassApplyConfiguration, opts metav1.ApplyOptions) (result *v1.IngressClass, err error) { if ingressClass == nil { return nil, fmt.Errorf("ingressClass provided to Apply must not be nil") } @@ -138,9 +137,9 @@ func (c *FakeIngressClasses) Apply(ctx context.Context, ingressClass *applyconfi return nil, fmt.Errorf("ingressClass.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(ingressclassesResource, *name, types.ApplyPatchType, data), &networkingv1.IngressClass{}) + Invokes(testing.NewRootPatchSubresourceAction(ingressclassesResource, *name, types.ApplyPatchType, data), &v1.IngressClass{}) if obj == nil { return nil, err } - return obj.(*networkingv1.IngressClass), err + return obj.(*v1.IngressClass), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/fake/fake_networkpolicy.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/fake/fake_networkpolicy.go index 16c10cac0d..be7413cb8f 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/fake/fake_networkpolicy.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/fake/fake_networkpolicy.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - networkingv1 "k8s.io/api/networking/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsnetworkingv1 "k8s.io/client-go/applyconfigurations/networking/v1" + networkingv1 "k8s.io/client-go/applyconfigurations/networking/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeNetworkPolicies struct { ns string } -var networkpoliciesResource = schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1", Resource: "networkpolicies"} +var networkpoliciesResource = v1.SchemeGroupVersion.WithResource("networkpolicies") -var networkpoliciesKind = schema.GroupVersionKind{Group: "networking.k8s.io", Version: "v1", Kind: "NetworkPolicy"} +var networkpoliciesKind = v1.SchemeGroupVersion.WithKind("NetworkPolicy") // Get takes name of the networkPolicy, and returns the corresponding networkPolicy object, and an error if there is any. -func (c *FakeNetworkPolicies) Get(ctx context.Context, name string, options v1.GetOptions) (result *networkingv1.NetworkPolicy, err error) { +func (c *FakeNetworkPolicies) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.NetworkPolicy, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(networkpoliciesResource, c.ns, name), &networkingv1.NetworkPolicy{}) + Invokes(testing.NewGetAction(networkpoliciesResource, c.ns, name), &v1.NetworkPolicy{}) if obj == nil { return nil, err } - return obj.(*networkingv1.NetworkPolicy), err + return obj.(*v1.NetworkPolicy), err } // List takes label and field selectors, and returns the list of NetworkPolicies that match those selectors. -func (c *FakeNetworkPolicies) List(ctx context.Context, opts v1.ListOptions) (result *networkingv1.NetworkPolicyList, err error) { +func (c *FakeNetworkPolicies) List(ctx context.Context, opts metav1.ListOptions) (result *v1.NetworkPolicyList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(networkpoliciesResource, networkpoliciesKind, c.ns, opts), &networkingv1.NetworkPolicyList{}) + Invokes(testing.NewListAction(networkpoliciesResource, networkpoliciesKind, c.ns, opts), &v1.NetworkPolicyList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeNetworkPolicies) List(ctx context.Context, opts v1.ListOptions) (re if label == nil { label = labels.Everything() } - list := &networkingv1.NetworkPolicyList{ListMeta: obj.(*networkingv1.NetworkPolicyList).ListMeta} - for _, item := range obj.(*networkingv1.NetworkPolicyList).Items { + list := &v1.NetworkPolicyList{ListMeta: obj.(*v1.NetworkPolicyList).ListMeta} + for _, item := range obj.(*v1.NetworkPolicyList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,75 +76,75 @@ func (c *FakeNetworkPolicies) List(ctx context.Context, opts v1.ListOptions) (re } // Watch returns a watch.Interface that watches the requested networkPolicies. -func (c *FakeNetworkPolicies) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeNetworkPolicies) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(networkpoliciesResource, c.ns, opts)) } // Create takes the representation of a networkPolicy and creates it. Returns the server's representation of the networkPolicy, and an error, if there is any. -func (c *FakeNetworkPolicies) Create(ctx context.Context, networkPolicy *networkingv1.NetworkPolicy, opts v1.CreateOptions) (result *networkingv1.NetworkPolicy, err error) { +func (c *FakeNetworkPolicies) Create(ctx context.Context, networkPolicy *v1.NetworkPolicy, opts metav1.CreateOptions) (result *v1.NetworkPolicy, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(networkpoliciesResource, c.ns, networkPolicy), &networkingv1.NetworkPolicy{}) + Invokes(testing.NewCreateAction(networkpoliciesResource, c.ns, networkPolicy), &v1.NetworkPolicy{}) if obj == nil { return nil, err } - return obj.(*networkingv1.NetworkPolicy), err + return obj.(*v1.NetworkPolicy), err } // Update takes the representation of a networkPolicy and updates it. Returns the server's representation of the networkPolicy, and an error, if there is any. -func (c *FakeNetworkPolicies) Update(ctx context.Context, networkPolicy *networkingv1.NetworkPolicy, opts v1.UpdateOptions) (result *networkingv1.NetworkPolicy, err error) { +func (c *FakeNetworkPolicies) Update(ctx context.Context, networkPolicy *v1.NetworkPolicy, opts metav1.UpdateOptions) (result *v1.NetworkPolicy, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(networkpoliciesResource, c.ns, networkPolicy), &networkingv1.NetworkPolicy{}) + Invokes(testing.NewUpdateAction(networkpoliciesResource, c.ns, networkPolicy), &v1.NetworkPolicy{}) if obj == nil { return nil, err } - return obj.(*networkingv1.NetworkPolicy), err + return obj.(*v1.NetworkPolicy), 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 *FakeNetworkPolicies) UpdateStatus(ctx context.Context, networkPolicy *networkingv1.NetworkPolicy, opts v1.UpdateOptions) (*networkingv1.NetworkPolicy, error) { +func (c *FakeNetworkPolicies) UpdateStatus(ctx context.Context, networkPolicy *v1.NetworkPolicy, opts metav1.UpdateOptions) (*v1.NetworkPolicy, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(networkpoliciesResource, "status", c.ns, networkPolicy), &networkingv1.NetworkPolicy{}) + Invokes(testing.NewUpdateSubresourceAction(networkpoliciesResource, "status", c.ns, networkPolicy), &v1.NetworkPolicy{}) if obj == nil { return nil, err } - return obj.(*networkingv1.NetworkPolicy), err + return obj.(*v1.NetworkPolicy), err } // Delete takes name of the networkPolicy and deletes it. Returns an error if one occurs. -func (c *FakeNetworkPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeNetworkPolicies) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(networkpoliciesResource, c.ns, name, opts), &networkingv1.NetworkPolicy{}) + Invokes(testing.NewDeleteActionWithOptions(networkpoliciesResource, c.ns, name, opts), &v1.NetworkPolicy{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeNetworkPolicies) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeNetworkPolicies) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(networkpoliciesResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &networkingv1.NetworkPolicyList{}) + _, err := c.Fake.Invokes(action, &v1.NetworkPolicyList{}) return err } // Patch applies the patch and returns the patched networkPolicy. -func (c *FakeNetworkPolicies) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *networkingv1.NetworkPolicy, err error) { +func (c *FakeNetworkPolicies) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.NetworkPolicy, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(networkpoliciesResource, c.ns, name, pt, data, subresources...), &networkingv1.NetworkPolicy{}) + Invokes(testing.NewPatchSubresourceAction(networkpoliciesResource, c.ns, name, pt, data, subresources...), &v1.NetworkPolicy{}) if obj == nil { return nil, err } - return obj.(*networkingv1.NetworkPolicy), err + return obj.(*v1.NetworkPolicy), err } // Apply takes the given apply declarative configuration, applies it and returns the applied networkPolicy. -func (c *FakeNetworkPolicies) Apply(ctx context.Context, networkPolicy *applyconfigurationsnetworkingv1.NetworkPolicyApplyConfiguration, opts v1.ApplyOptions) (result *networkingv1.NetworkPolicy, err error) { +func (c *FakeNetworkPolicies) Apply(ctx context.Context, networkPolicy *networkingv1.NetworkPolicyApplyConfiguration, opts metav1.ApplyOptions) (result *v1.NetworkPolicy, err error) { if networkPolicy == nil { return nil, fmt.Errorf("networkPolicy provided to Apply must not be nil") } @@ -158,17 +157,17 @@ func (c *FakeNetworkPolicies) Apply(ctx context.Context, networkPolicy *applycon return nil, fmt.Errorf("networkPolicy.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(networkpoliciesResource, c.ns, *name, types.ApplyPatchType, data), &networkingv1.NetworkPolicy{}) + Invokes(testing.NewPatchSubresourceAction(networkpoliciesResource, c.ns, *name, types.ApplyPatchType, data), &v1.NetworkPolicy{}) if obj == nil { return nil, err } - return obj.(*networkingv1.NetworkPolicy), err + return obj.(*v1.NetworkPolicy), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeNetworkPolicies) ApplyStatus(ctx context.Context, networkPolicy *applyconfigurationsnetworkingv1.NetworkPolicyApplyConfiguration, opts v1.ApplyOptions) (result *networkingv1.NetworkPolicy, err error) { +func (c *FakeNetworkPolicies) ApplyStatus(ctx context.Context, networkPolicy *networkingv1.NetworkPolicyApplyConfiguration, opts metav1.ApplyOptions) (result *v1.NetworkPolicy, err error) { if networkPolicy == nil { return nil, fmt.Errorf("networkPolicy provided to Apply must not be nil") } @@ -181,10 +180,10 @@ func (c *FakeNetworkPolicies) ApplyStatus(ctx context.Context, networkPolicy *ap return nil, fmt.Errorf("networkPolicy.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(networkpoliciesResource, c.ns, *name, types.ApplyPatchType, data, "status"), &networkingv1.NetworkPolicy{}) + Invokes(testing.NewPatchSubresourceAction(networkpoliciesResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.NetworkPolicy{}) if obj == nil { return nil, err } - return obj.(*networkingv1.NetworkPolicy), err + return obj.(*v1.NetworkPolicy), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/fake/fake_clustercidr.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/fake/fake_clustercidr.go index ca0352d390..592e9fc63d 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/fake/fake_clustercidr.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/fake/fake_clustercidr.go @@ -26,7 +26,6 @@ import ( v1alpha1 "k8s.io/api/networking/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" networkingv1alpha1 "k8s.io/client-go/applyconfigurations/networking/v1alpha1" @@ -38,9 +37,9 @@ type FakeClusterCIDRs struct { Fake *FakeNetworkingV1alpha1 } -var clustercidrsResource = schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1alpha1", Resource: "clustercidrs"} +var clustercidrsResource = v1alpha1.SchemeGroupVersion.WithResource("clustercidrs") -var clustercidrsKind = schema.GroupVersionKind{Group: "networking.k8s.io", Version: "v1alpha1", Kind: "ClusterCIDR"} +var clustercidrsKind = v1alpha1.SchemeGroupVersion.WithKind("ClusterCIDR") // Get takes name of the clusterCIDR, and returns the corresponding clusterCIDR object, and an error if there is any. func (c *FakeClusterCIDRs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterCIDR, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/fake/fake_ipaddress.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/fake/fake_ipaddress.go new file mode 100644 index 0000000000..4db8df68cb --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/fake/fake_ipaddress.go @@ -0,0 +1,145 @@ +/* +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 + +import ( + "context" + json "encoding/json" + "fmt" + + v1alpha1 "k8s.io/api/networking/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + networkingv1alpha1 "k8s.io/client-go/applyconfigurations/networking/v1alpha1" + testing "k8s.io/client-go/testing" +) + +// FakeIPAddresses implements IPAddressInterface +type FakeIPAddresses struct { + Fake *FakeNetworkingV1alpha1 +} + +var ipaddressesResource = v1alpha1.SchemeGroupVersion.WithResource("ipaddresses") + +var ipaddressesKind = v1alpha1.SchemeGroupVersion.WithKind("IPAddress") + +// Get takes name of the iPAddress, and returns the corresponding iPAddress object, and an error if there is any. +func (c *FakeIPAddresses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.IPAddress, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(ipaddressesResource, name), &v1alpha1.IPAddress{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.IPAddress), err +} + +// List takes label and field selectors, and returns the list of IPAddresses that match those selectors. +func (c *FakeIPAddresses) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.IPAddressList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(ipaddressesResource, ipaddressesKind, opts), &v1alpha1.IPAddressList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.IPAddressList{ListMeta: obj.(*v1alpha1.IPAddressList).ListMeta} + for _, item := range obj.(*v1alpha1.IPAddressList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested iPAddresses. +func (c *FakeIPAddresses) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(ipaddressesResource, opts)) +} + +// Create takes the representation of a iPAddress and creates it. Returns the server's representation of the iPAddress, and an error, if there is any. +func (c *FakeIPAddresses) Create(ctx context.Context, iPAddress *v1alpha1.IPAddress, opts v1.CreateOptions) (result *v1alpha1.IPAddress, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(ipaddressesResource, iPAddress), &v1alpha1.IPAddress{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.IPAddress), err +} + +// Update takes the representation of a iPAddress and updates it. Returns the server's representation of the iPAddress, and an error, if there is any. +func (c *FakeIPAddresses) Update(ctx context.Context, iPAddress *v1alpha1.IPAddress, opts v1.UpdateOptions) (result *v1alpha1.IPAddress, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(ipaddressesResource, iPAddress), &v1alpha1.IPAddress{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.IPAddress), err +} + +// Delete takes name of the iPAddress and deletes it. Returns an error if one occurs. +func (c *FakeIPAddresses) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteActionWithOptions(ipaddressesResource, name, opts), &v1alpha1.IPAddress{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeIPAddresses) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(ipaddressesResource, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha1.IPAddressList{}) + return err +} + +// Patch applies the patch and returns the patched iPAddress. +func (c *FakeIPAddresses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.IPAddress, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(ipaddressesResource, name, pt, data, subresources...), &v1alpha1.IPAddress{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.IPAddress), err +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied iPAddress. +func (c *FakeIPAddresses) Apply(ctx context.Context, iPAddress *networkingv1alpha1.IPAddressApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.IPAddress, err error) { + if iPAddress == nil { + return nil, fmt.Errorf("iPAddress provided to Apply must not be nil") + } + data, err := json.Marshal(iPAddress) + if err != nil { + return nil, err + } + name := iPAddress.Name + if name == nil { + return nil, fmt.Errorf("iPAddress.Name must be provided to Apply") + } + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(ipaddressesResource, *name, types.ApplyPatchType, data), &v1alpha1.IPAddress{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.IPAddress), err +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/fake/fake_networking_client.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/fake/fake_networking_client.go index 96979aa881..2d063836b5 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/fake/fake_networking_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/fake/fake_networking_client.go @@ -32,6 +32,10 @@ func (c *FakeNetworkingV1alpha1) ClusterCIDRs() v1alpha1.ClusterCIDRInterface { return &FakeClusterCIDRs{c} } +func (c *FakeNetworkingV1alpha1) IPAddresses() v1alpha1.IPAddressInterface { + return &FakeIPAddresses{c} +} + // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. func (c *FakeNetworkingV1alpha1) RESTClient() rest.Interface { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/generated_expansion.go index ab41abb7d0..9c2979d6c4 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/generated_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/generated_expansion.go @@ -19,3 +19,5 @@ limitations under the License. package v1alpha1 type ClusterCIDRExpansion interface{} + +type IPAddressExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/ipaddress.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/ipaddress.go new file mode 100644 index 0000000000..fff193d68d --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/ipaddress.go @@ -0,0 +1,197 @@ +/* +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 v1alpha1 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha1 "k8s.io/api/networking/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + networkingv1alpha1 "k8s.io/client-go/applyconfigurations/networking/v1alpha1" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// IPAddressesGetter has a method to return a IPAddressInterface. +// A group's client should implement this interface. +type IPAddressesGetter interface { + IPAddresses() IPAddressInterface +} + +// IPAddressInterface has methods to work with IPAddress resources. +type IPAddressInterface interface { + Create(ctx context.Context, iPAddress *v1alpha1.IPAddress, opts v1.CreateOptions) (*v1alpha1.IPAddress, error) + Update(ctx context.Context, iPAddress *v1alpha1.IPAddress, opts v1.UpdateOptions) (*v1alpha1.IPAddress, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.IPAddress, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.IPAddressList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.IPAddress, err error) + Apply(ctx context.Context, iPAddress *networkingv1alpha1.IPAddressApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.IPAddress, err error) + IPAddressExpansion +} + +// iPAddresses implements IPAddressInterface +type iPAddresses struct { + client rest.Interface +} + +// newIPAddresses returns a IPAddresses +func newIPAddresses(c *NetworkingV1alpha1Client) *iPAddresses { + return &iPAddresses{ + client: c.RESTClient(), + } +} + +// Get takes name of the iPAddress, and returns the corresponding iPAddress object, and an error if there is any. +func (c *iPAddresses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.IPAddress, err error) { + result = &v1alpha1.IPAddress{} + err = c.client.Get(). + Resource("ipaddresses"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of IPAddresses that match those selectors. +func (c *iPAddresses) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.IPAddressList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.IPAddressList{} + err = c.client.Get(). + Resource("ipaddresses"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested iPAddresses. +func (c *iPAddresses) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("ipaddresses"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a iPAddress and creates it. Returns the server's representation of the iPAddress, and an error, if there is any. +func (c *iPAddresses) Create(ctx context.Context, iPAddress *v1alpha1.IPAddress, opts v1.CreateOptions) (result *v1alpha1.IPAddress, err error) { + result = &v1alpha1.IPAddress{} + err = c.client.Post(). + Resource("ipaddresses"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(iPAddress). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a iPAddress and updates it. Returns the server's representation of the iPAddress, and an error, if there is any. +func (c *iPAddresses) Update(ctx context.Context, iPAddress *v1alpha1.IPAddress, opts v1.UpdateOptions) (result *v1alpha1.IPAddress, err error) { + result = &v1alpha1.IPAddress{} + err = c.client.Put(). + Resource("ipaddresses"). + Name(iPAddress.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(iPAddress). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the iPAddress and deletes it. Returns an error if one occurs. +func (c *iPAddresses) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("ipaddresses"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *iPAddresses) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("ipaddresses"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched iPAddress. +func (c *iPAddresses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.IPAddress, err error) { + result = &v1alpha1.IPAddress{} + err = c.client.Patch(pt). + Resource("ipaddresses"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied iPAddress. +func (c *iPAddresses) Apply(ctx context.Context, iPAddress *networkingv1alpha1.IPAddressApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.IPAddress, err error) { + if iPAddress == nil { + return nil, fmt.Errorf("iPAddress provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(iPAddress) + if err != nil { + return nil, err + } + name := iPAddress.Name + if name == nil { + return nil, fmt.Errorf("iPAddress.Name must be provided to Apply") + } + result = &v1alpha1.IPAddress{} + err = c.client.Patch(types.ApplyPatchType). + Resource("ipaddresses"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/networking_client.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/networking_client.go index ccb5933163..884c846f59 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/networking_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/networking_client.go @@ -29,6 +29,7 @@ import ( type NetworkingV1alpha1Interface interface { RESTClient() rest.Interface ClusterCIDRsGetter + IPAddressesGetter } // NetworkingV1alpha1Client is used to interact with features provided by the networking.k8s.io group. @@ -40,6 +41,10 @@ func (c *NetworkingV1alpha1Client) ClusterCIDRs() ClusterCIDRInterface { return newClusterCIDRs(c) } +func (c *NetworkingV1alpha1Client) IPAddresses() IPAddressInterface { + return newIPAddresses(c) +} + // NewForConfig creates a new NetworkingV1alpha1Client for the given config. // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), // where httpClient was generated with rest.HTTPClientFor(c). diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1beta1/fake/fake_ingress.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1beta1/fake/fake_ingress.go index 349196c534..7a3b861be0 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1beta1/fake/fake_ingress.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1beta1/fake/fake_ingress.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/networking/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" networkingv1beta1 "k8s.io/client-go/applyconfigurations/networking/v1beta1" @@ -39,9 +38,9 @@ type FakeIngresses struct { ns string } -var ingressesResource = schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1beta1", Resource: "ingresses"} +var ingressesResource = v1beta1.SchemeGroupVersion.WithResource("ingresses") -var ingressesKind = schema.GroupVersionKind{Group: "networking.k8s.io", Version: "v1beta1", Kind: "Ingress"} +var ingressesKind = v1beta1.SchemeGroupVersion.WithKind("Ingress") // Get takes name of the ingress, and returns the corresponding ingress object, and an error if there is any. func (c *FakeIngresses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Ingress, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1beta1/fake/fake_ingressclass.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1beta1/fake/fake_ingressclass.go index 6ef8d1eddd..1804e61fc3 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1beta1/fake/fake_ingressclass.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1beta1/fake/fake_ingressclass.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/networking/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" networkingv1beta1 "k8s.io/client-go/applyconfigurations/networking/v1beta1" @@ -38,9 +37,9 @@ type FakeIngressClasses struct { Fake *FakeNetworkingV1beta1 } -var ingressclassesResource = schema.GroupVersionResource{Group: "networking.k8s.io", Version: "v1beta1", Resource: "ingressclasses"} +var ingressclassesResource = v1beta1.SchemeGroupVersion.WithResource("ingressclasses") -var ingressclassesKind = schema.GroupVersionKind{Group: "networking.k8s.io", Version: "v1beta1", Kind: "IngressClass"} +var ingressclassesKind = v1beta1.SchemeGroupVersion.WithKind("IngressClass") // Get takes name of the ingressClass, and returns the corresponding ingressClass object, and an error if there is any. func (c *FakeIngressClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.IngressClass, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/node/v1/fake/fake_runtimeclass.go b/vendor/k8s.io/client-go/kubernetes/typed/node/v1/fake/fake_runtimeclass.go index 3a1aaf1b60..35cfbcae4b 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/node/v1/fake/fake_runtimeclass.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/node/v1/fake/fake_runtimeclass.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - nodev1 "k8s.io/api/node/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/node/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsnodev1 "k8s.io/client-go/applyconfigurations/node/v1" + nodev1 "k8s.io/client-go/applyconfigurations/node/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakeRuntimeClasses struct { Fake *FakeNodeV1 } -var runtimeclassesResource = schema.GroupVersionResource{Group: "node.k8s.io", Version: "v1", Resource: "runtimeclasses"} +var runtimeclassesResource = v1.SchemeGroupVersion.WithResource("runtimeclasses") -var runtimeclassesKind = schema.GroupVersionKind{Group: "node.k8s.io", Version: "v1", Kind: "RuntimeClass"} +var runtimeclassesKind = v1.SchemeGroupVersion.WithKind("RuntimeClass") // Get takes name of the runtimeClass, and returns the corresponding runtimeClass object, and an error if there is any. -func (c *FakeRuntimeClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *nodev1.RuntimeClass, err error) { +func (c *FakeRuntimeClasses) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.RuntimeClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(runtimeclassesResource, name), &nodev1.RuntimeClass{}) + Invokes(testing.NewRootGetAction(runtimeclassesResource, name), &v1.RuntimeClass{}) if obj == nil { return nil, err } - return obj.(*nodev1.RuntimeClass), err + return obj.(*v1.RuntimeClass), err } // List takes label and field selectors, and returns the list of RuntimeClasses that match those selectors. -func (c *FakeRuntimeClasses) List(ctx context.Context, opts v1.ListOptions) (result *nodev1.RuntimeClassList, err error) { +func (c *FakeRuntimeClasses) List(ctx context.Context, opts metav1.ListOptions) (result *v1.RuntimeClassList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(runtimeclassesResource, runtimeclassesKind, opts), &nodev1.RuntimeClassList{}) + Invokes(testing.NewRootListAction(runtimeclassesResource, runtimeclassesKind, opts), &v1.RuntimeClassList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakeRuntimeClasses) List(ctx context.Context, opts v1.ListOptions) (res if label == nil { label = labels.Everything() } - list := &nodev1.RuntimeClassList{ListMeta: obj.(*nodev1.RuntimeClassList).ListMeta} - for _, item := range obj.(*nodev1.RuntimeClassList).Items { + list := &v1.RuntimeClassList{ListMeta: obj.(*v1.RuntimeClassList).ListMeta} + for _, item := range obj.(*v1.RuntimeClassList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,58 +73,58 @@ func (c *FakeRuntimeClasses) List(ctx context.Context, opts v1.ListOptions) (res } // Watch returns a watch.Interface that watches the requested runtimeClasses. -func (c *FakeRuntimeClasses) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeRuntimeClasses) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(runtimeclassesResource, opts)) } // Create takes the representation of a runtimeClass and creates it. Returns the server's representation of the runtimeClass, and an error, if there is any. -func (c *FakeRuntimeClasses) Create(ctx context.Context, runtimeClass *nodev1.RuntimeClass, opts v1.CreateOptions) (result *nodev1.RuntimeClass, err error) { +func (c *FakeRuntimeClasses) Create(ctx context.Context, runtimeClass *v1.RuntimeClass, opts metav1.CreateOptions) (result *v1.RuntimeClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(runtimeclassesResource, runtimeClass), &nodev1.RuntimeClass{}) + Invokes(testing.NewRootCreateAction(runtimeclassesResource, runtimeClass), &v1.RuntimeClass{}) if obj == nil { return nil, err } - return obj.(*nodev1.RuntimeClass), err + return obj.(*v1.RuntimeClass), err } // Update takes the representation of a runtimeClass and updates it. Returns the server's representation of the runtimeClass, and an error, if there is any. -func (c *FakeRuntimeClasses) Update(ctx context.Context, runtimeClass *nodev1.RuntimeClass, opts v1.UpdateOptions) (result *nodev1.RuntimeClass, err error) { +func (c *FakeRuntimeClasses) Update(ctx context.Context, runtimeClass *v1.RuntimeClass, opts metav1.UpdateOptions) (result *v1.RuntimeClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(runtimeclassesResource, runtimeClass), &nodev1.RuntimeClass{}) + Invokes(testing.NewRootUpdateAction(runtimeclassesResource, runtimeClass), &v1.RuntimeClass{}) if obj == nil { return nil, err } - return obj.(*nodev1.RuntimeClass), err + return obj.(*v1.RuntimeClass), err } // Delete takes name of the runtimeClass and deletes it. Returns an error if one occurs. -func (c *FakeRuntimeClasses) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeRuntimeClasses) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(runtimeclassesResource, name, opts), &nodev1.RuntimeClass{}) + Invokes(testing.NewRootDeleteActionWithOptions(runtimeclassesResource, name, opts), &v1.RuntimeClass{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeRuntimeClasses) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeRuntimeClasses) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(runtimeclassesResource, listOpts) - _, err := c.Fake.Invokes(action, &nodev1.RuntimeClassList{}) + _, err := c.Fake.Invokes(action, &v1.RuntimeClassList{}) return err } // Patch applies the patch and returns the patched runtimeClass. -func (c *FakeRuntimeClasses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *nodev1.RuntimeClass, err error) { +func (c *FakeRuntimeClasses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RuntimeClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(runtimeclassesResource, name, pt, data, subresources...), &nodev1.RuntimeClass{}) + Invokes(testing.NewRootPatchSubresourceAction(runtimeclassesResource, name, pt, data, subresources...), &v1.RuntimeClass{}) if obj == nil { return nil, err } - return obj.(*nodev1.RuntimeClass), err + return obj.(*v1.RuntimeClass), err } // Apply takes the given apply declarative configuration, applies it and returns the applied runtimeClass. -func (c *FakeRuntimeClasses) Apply(ctx context.Context, runtimeClass *applyconfigurationsnodev1.RuntimeClassApplyConfiguration, opts v1.ApplyOptions) (result *nodev1.RuntimeClass, err error) { +func (c *FakeRuntimeClasses) Apply(ctx context.Context, runtimeClass *nodev1.RuntimeClassApplyConfiguration, opts metav1.ApplyOptions) (result *v1.RuntimeClass, err error) { if runtimeClass == nil { return nil, fmt.Errorf("runtimeClass provided to Apply must not be nil") } @@ -138,9 +137,9 @@ func (c *FakeRuntimeClasses) Apply(ctx context.Context, runtimeClass *applyconfi return nil, fmt.Errorf("runtimeClass.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(runtimeclassesResource, *name, types.ApplyPatchType, data), &nodev1.RuntimeClass{}) + Invokes(testing.NewRootPatchSubresourceAction(runtimeclassesResource, *name, types.ApplyPatchType, data), &v1.RuntimeClass{}) if obj == nil { return nil, err } - return obj.(*nodev1.RuntimeClass), err + return obj.(*v1.RuntimeClass), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/node/v1alpha1/fake/fake_runtimeclass.go b/vendor/k8s.io/client-go/kubernetes/typed/node/v1alpha1/fake/fake_runtimeclass.go index 4b6387943d..2ff7d3f973 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/node/v1alpha1/fake/fake_runtimeclass.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/node/v1alpha1/fake/fake_runtimeclass.go @@ -26,7 +26,6 @@ import ( v1alpha1 "k8s.io/api/node/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" nodev1alpha1 "k8s.io/client-go/applyconfigurations/node/v1alpha1" @@ -38,9 +37,9 @@ type FakeRuntimeClasses struct { Fake *FakeNodeV1alpha1 } -var runtimeclassesResource = schema.GroupVersionResource{Group: "node.k8s.io", Version: "v1alpha1", Resource: "runtimeclasses"} +var runtimeclassesResource = v1alpha1.SchemeGroupVersion.WithResource("runtimeclasses") -var runtimeclassesKind = schema.GroupVersionKind{Group: "node.k8s.io", Version: "v1alpha1", Kind: "RuntimeClass"} +var runtimeclassesKind = v1alpha1.SchemeGroupVersion.WithKind("RuntimeClass") // Get takes name of the runtimeClass, and returns the corresponding runtimeClass object, and an error if there is any. func (c *FakeRuntimeClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.RuntimeClass, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/node/v1beta1/fake/fake_runtimeclass.go b/vendor/k8s.io/client-go/kubernetes/typed/node/v1beta1/fake/fake_runtimeclass.go index 191162114b..e6552f9aca 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/node/v1beta1/fake/fake_runtimeclass.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/node/v1beta1/fake/fake_runtimeclass.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/node/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" nodev1beta1 "k8s.io/client-go/applyconfigurations/node/v1beta1" @@ -38,9 +37,9 @@ type FakeRuntimeClasses struct { Fake *FakeNodeV1beta1 } -var runtimeclassesResource = schema.GroupVersionResource{Group: "node.k8s.io", Version: "v1beta1", Resource: "runtimeclasses"} +var runtimeclassesResource = v1beta1.SchemeGroupVersion.WithResource("runtimeclasses") -var runtimeclassesKind = schema.GroupVersionKind{Group: "node.k8s.io", Version: "v1beta1", Kind: "RuntimeClass"} +var runtimeclassesKind = v1beta1.SchemeGroupVersion.WithKind("RuntimeClass") // Get takes name of the runtimeClass, and returns the corresponding runtimeClass object, and an error if there is any. func (c *FakeRuntimeClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.RuntimeClass, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/policy/v1/fake/fake_poddisruptionbudget.go b/vendor/k8s.io/client-go/kubernetes/typed/policy/v1/fake/fake_poddisruptionbudget.go index 8023e2cd6f..7b5f51caf4 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/policy/v1/fake/fake_poddisruptionbudget.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/policy/v1/fake/fake_poddisruptionbudget.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - policyv1 "k8s.io/api/policy/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/policy/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationspolicyv1 "k8s.io/client-go/applyconfigurations/policy/v1" + policyv1 "k8s.io/client-go/applyconfigurations/policy/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakePodDisruptionBudgets struct { ns string } -var poddisruptionbudgetsResource = schema.GroupVersionResource{Group: "policy", Version: "v1", Resource: "poddisruptionbudgets"} +var poddisruptionbudgetsResource = v1.SchemeGroupVersion.WithResource("poddisruptionbudgets") -var poddisruptionbudgetsKind = schema.GroupVersionKind{Group: "policy", Version: "v1", Kind: "PodDisruptionBudget"} +var poddisruptionbudgetsKind = v1.SchemeGroupVersion.WithKind("PodDisruptionBudget") // Get takes name of the podDisruptionBudget, and returns the corresponding podDisruptionBudget object, and an error if there is any. -func (c *FakePodDisruptionBudgets) Get(ctx context.Context, name string, options v1.GetOptions) (result *policyv1.PodDisruptionBudget, err error) { +func (c *FakePodDisruptionBudgets) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.PodDisruptionBudget, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(poddisruptionbudgetsResource, c.ns, name), &policyv1.PodDisruptionBudget{}) + Invokes(testing.NewGetAction(poddisruptionbudgetsResource, c.ns, name), &v1.PodDisruptionBudget{}) if obj == nil { return nil, err } - return obj.(*policyv1.PodDisruptionBudget), err + return obj.(*v1.PodDisruptionBudget), err } // List takes label and field selectors, and returns the list of PodDisruptionBudgets that match those selectors. -func (c *FakePodDisruptionBudgets) List(ctx context.Context, opts v1.ListOptions) (result *policyv1.PodDisruptionBudgetList, err error) { +func (c *FakePodDisruptionBudgets) List(ctx context.Context, opts metav1.ListOptions) (result *v1.PodDisruptionBudgetList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(poddisruptionbudgetsResource, poddisruptionbudgetsKind, c.ns, opts), &policyv1.PodDisruptionBudgetList{}) + Invokes(testing.NewListAction(poddisruptionbudgetsResource, poddisruptionbudgetsKind, c.ns, opts), &v1.PodDisruptionBudgetList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakePodDisruptionBudgets) List(ctx context.Context, opts v1.ListOptions if label == nil { label = labels.Everything() } - list := &policyv1.PodDisruptionBudgetList{ListMeta: obj.(*policyv1.PodDisruptionBudgetList).ListMeta} - for _, item := range obj.(*policyv1.PodDisruptionBudgetList).Items { + list := &v1.PodDisruptionBudgetList{ListMeta: obj.(*v1.PodDisruptionBudgetList).ListMeta} + for _, item := range obj.(*v1.PodDisruptionBudgetList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,75 +76,75 @@ func (c *FakePodDisruptionBudgets) List(ctx context.Context, opts v1.ListOptions } // Watch returns a watch.Interface that watches the requested podDisruptionBudgets. -func (c *FakePodDisruptionBudgets) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakePodDisruptionBudgets) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(poddisruptionbudgetsResource, c.ns, opts)) } // Create takes the representation of a podDisruptionBudget and creates it. Returns the server's representation of the podDisruptionBudget, and an error, if there is any. -func (c *FakePodDisruptionBudgets) Create(ctx context.Context, podDisruptionBudget *policyv1.PodDisruptionBudget, opts v1.CreateOptions) (result *policyv1.PodDisruptionBudget, err error) { +func (c *FakePodDisruptionBudgets) Create(ctx context.Context, podDisruptionBudget *v1.PodDisruptionBudget, opts metav1.CreateOptions) (result *v1.PodDisruptionBudget, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(poddisruptionbudgetsResource, c.ns, podDisruptionBudget), &policyv1.PodDisruptionBudget{}) + Invokes(testing.NewCreateAction(poddisruptionbudgetsResource, c.ns, podDisruptionBudget), &v1.PodDisruptionBudget{}) if obj == nil { return nil, err } - return obj.(*policyv1.PodDisruptionBudget), err + return obj.(*v1.PodDisruptionBudget), err } // Update takes the representation of a podDisruptionBudget and updates it. Returns the server's representation of the podDisruptionBudget, and an error, if there is any. -func (c *FakePodDisruptionBudgets) Update(ctx context.Context, podDisruptionBudget *policyv1.PodDisruptionBudget, opts v1.UpdateOptions) (result *policyv1.PodDisruptionBudget, err error) { +func (c *FakePodDisruptionBudgets) Update(ctx context.Context, podDisruptionBudget *v1.PodDisruptionBudget, opts metav1.UpdateOptions) (result *v1.PodDisruptionBudget, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(poddisruptionbudgetsResource, c.ns, podDisruptionBudget), &policyv1.PodDisruptionBudget{}) + Invokes(testing.NewUpdateAction(poddisruptionbudgetsResource, c.ns, podDisruptionBudget), &v1.PodDisruptionBudget{}) if obj == nil { return nil, err } - return obj.(*policyv1.PodDisruptionBudget), err + return obj.(*v1.PodDisruptionBudget), 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 *FakePodDisruptionBudgets) UpdateStatus(ctx context.Context, podDisruptionBudget *policyv1.PodDisruptionBudget, opts v1.UpdateOptions) (*policyv1.PodDisruptionBudget, error) { +func (c *FakePodDisruptionBudgets) UpdateStatus(ctx context.Context, podDisruptionBudget *v1.PodDisruptionBudget, opts metav1.UpdateOptions) (*v1.PodDisruptionBudget, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(poddisruptionbudgetsResource, "status", c.ns, podDisruptionBudget), &policyv1.PodDisruptionBudget{}) + Invokes(testing.NewUpdateSubresourceAction(poddisruptionbudgetsResource, "status", c.ns, podDisruptionBudget), &v1.PodDisruptionBudget{}) if obj == nil { return nil, err } - return obj.(*policyv1.PodDisruptionBudget), err + return obj.(*v1.PodDisruptionBudget), err } // Delete takes name of the podDisruptionBudget and deletes it. Returns an error if one occurs. -func (c *FakePodDisruptionBudgets) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakePodDisruptionBudgets) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(poddisruptionbudgetsResource, c.ns, name, opts), &policyv1.PodDisruptionBudget{}) + Invokes(testing.NewDeleteActionWithOptions(poddisruptionbudgetsResource, c.ns, name, opts), &v1.PodDisruptionBudget{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakePodDisruptionBudgets) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakePodDisruptionBudgets) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(poddisruptionbudgetsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &policyv1.PodDisruptionBudgetList{}) + _, err := c.Fake.Invokes(action, &v1.PodDisruptionBudgetList{}) return err } // Patch applies the patch and returns the patched podDisruptionBudget. -func (c *FakePodDisruptionBudgets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *policyv1.PodDisruptionBudget, err error) { +func (c *FakePodDisruptionBudgets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.PodDisruptionBudget, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(poddisruptionbudgetsResource, c.ns, name, pt, data, subresources...), &policyv1.PodDisruptionBudget{}) + Invokes(testing.NewPatchSubresourceAction(poddisruptionbudgetsResource, c.ns, name, pt, data, subresources...), &v1.PodDisruptionBudget{}) if obj == nil { return nil, err } - return obj.(*policyv1.PodDisruptionBudget), err + return obj.(*v1.PodDisruptionBudget), err } // Apply takes the given apply declarative configuration, applies it and returns the applied podDisruptionBudget. -func (c *FakePodDisruptionBudgets) Apply(ctx context.Context, podDisruptionBudget *applyconfigurationspolicyv1.PodDisruptionBudgetApplyConfiguration, opts v1.ApplyOptions) (result *policyv1.PodDisruptionBudget, err error) { +func (c *FakePodDisruptionBudgets) Apply(ctx context.Context, podDisruptionBudget *policyv1.PodDisruptionBudgetApplyConfiguration, opts metav1.ApplyOptions) (result *v1.PodDisruptionBudget, err error) { if podDisruptionBudget == nil { return nil, fmt.Errorf("podDisruptionBudget provided to Apply must not be nil") } @@ -158,17 +157,17 @@ func (c *FakePodDisruptionBudgets) Apply(ctx context.Context, podDisruptionBudge return nil, fmt.Errorf("podDisruptionBudget.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(poddisruptionbudgetsResource, c.ns, *name, types.ApplyPatchType, data), &policyv1.PodDisruptionBudget{}) + Invokes(testing.NewPatchSubresourceAction(poddisruptionbudgetsResource, c.ns, *name, types.ApplyPatchType, data), &v1.PodDisruptionBudget{}) if obj == nil { return nil, err } - return obj.(*policyv1.PodDisruptionBudget), err + return obj.(*v1.PodDisruptionBudget), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakePodDisruptionBudgets) ApplyStatus(ctx context.Context, podDisruptionBudget *applyconfigurationspolicyv1.PodDisruptionBudgetApplyConfiguration, opts v1.ApplyOptions) (result *policyv1.PodDisruptionBudget, err error) { +func (c *FakePodDisruptionBudgets) ApplyStatus(ctx context.Context, podDisruptionBudget *policyv1.PodDisruptionBudgetApplyConfiguration, opts metav1.ApplyOptions) (result *v1.PodDisruptionBudget, err error) { if podDisruptionBudget == nil { return nil, fmt.Errorf("podDisruptionBudget provided to Apply must not be nil") } @@ -181,10 +180,10 @@ func (c *FakePodDisruptionBudgets) ApplyStatus(ctx context.Context, podDisruptio return nil, fmt.Errorf("podDisruptionBudget.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(poddisruptionbudgetsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &policyv1.PodDisruptionBudget{}) + Invokes(testing.NewPatchSubresourceAction(poddisruptionbudgetsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.PodDisruptionBudget{}) if obj == nil { return nil, err } - return obj.(*policyv1.PodDisruptionBudget), err + return obj.(*v1.PodDisruptionBudget), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/policy/v1beta1/fake/fake_poddisruptionbudget.go b/vendor/k8s.io/client-go/kubernetes/typed/policy/v1beta1/fake/fake_poddisruptionbudget.go index d1c856754c..bcee8e7774 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/policy/v1beta1/fake/fake_poddisruptionbudget.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/policy/v1beta1/fake/fake_poddisruptionbudget.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/policy/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" policyv1beta1 "k8s.io/client-go/applyconfigurations/policy/v1beta1" @@ -39,9 +38,9 @@ type FakePodDisruptionBudgets struct { ns string } -var poddisruptionbudgetsResource = schema.GroupVersionResource{Group: "policy", Version: "v1beta1", Resource: "poddisruptionbudgets"} +var poddisruptionbudgetsResource = v1beta1.SchemeGroupVersion.WithResource("poddisruptionbudgets") -var poddisruptionbudgetsKind = schema.GroupVersionKind{Group: "policy", Version: "v1beta1", Kind: "PodDisruptionBudget"} +var poddisruptionbudgetsKind = v1beta1.SchemeGroupVersion.WithKind("PodDisruptionBudget") // Get takes name of the podDisruptionBudget, and returns the corresponding podDisruptionBudget object, and an error if there is any. func (c *FakePodDisruptionBudgets) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.PodDisruptionBudget, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/policy/v1beta1/fake/fake_podsecuritypolicy.go b/vendor/k8s.io/client-go/kubernetes/typed/policy/v1beta1/fake/fake_podsecuritypolicy.go index 614d4e799d..ade1aab7f0 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/policy/v1beta1/fake/fake_podsecuritypolicy.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/policy/v1beta1/fake/fake_podsecuritypolicy.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/policy/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" policyv1beta1 "k8s.io/client-go/applyconfigurations/policy/v1beta1" @@ -38,9 +37,9 @@ type FakePodSecurityPolicies struct { Fake *FakePolicyV1beta1 } -var podsecuritypoliciesResource = schema.GroupVersionResource{Group: "policy", Version: "v1beta1", Resource: "podsecuritypolicies"} +var podsecuritypoliciesResource = v1beta1.SchemeGroupVersion.WithResource("podsecuritypolicies") -var podsecuritypoliciesKind = schema.GroupVersionKind{Group: "policy", Version: "v1beta1", Kind: "PodSecurityPolicy"} +var podsecuritypoliciesKind = v1beta1.SchemeGroupVersion.WithKind("PodSecurityPolicy") // Get takes name of the podSecurityPolicy, and returns the corresponding podSecurityPolicy object, and an error if there is any. func (c *FakePodSecurityPolicies) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.PodSecurityPolicy, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_clusterrole.go b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_clusterrole.go index 21a32ca043..5add33ddfb 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_clusterrole.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_clusterrole.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - rbacv1 "k8s.io/api/rbac/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsrbacv1 "k8s.io/client-go/applyconfigurations/rbac/v1" + rbacv1 "k8s.io/client-go/applyconfigurations/rbac/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakeClusterRoles struct { Fake *FakeRbacV1 } -var clusterrolesResource = schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterroles"} +var clusterrolesResource = v1.SchemeGroupVersion.WithResource("clusterroles") -var clusterrolesKind = schema.GroupVersionKind{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "ClusterRole"} +var clusterrolesKind = v1.SchemeGroupVersion.WithKind("ClusterRole") // Get takes name of the clusterRole, and returns the corresponding clusterRole object, and an error if there is any. -func (c *FakeClusterRoles) Get(ctx context.Context, name string, options v1.GetOptions) (result *rbacv1.ClusterRole, err error) { +func (c *FakeClusterRoles) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ClusterRole, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(clusterrolesResource, name), &rbacv1.ClusterRole{}) + Invokes(testing.NewRootGetAction(clusterrolesResource, name), &v1.ClusterRole{}) if obj == nil { return nil, err } - return obj.(*rbacv1.ClusterRole), err + return obj.(*v1.ClusterRole), err } // List takes label and field selectors, and returns the list of ClusterRoles that match those selectors. -func (c *FakeClusterRoles) List(ctx context.Context, opts v1.ListOptions) (result *rbacv1.ClusterRoleList, err error) { +func (c *FakeClusterRoles) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ClusterRoleList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(clusterrolesResource, clusterrolesKind, opts), &rbacv1.ClusterRoleList{}) + Invokes(testing.NewRootListAction(clusterrolesResource, clusterrolesKind, opts), &v1.ClusterRoleList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakeClusterRoles) List(ctx context.Context, opts v1.ListOptions) (resul if label == nil { label = labels.Everything() } - list := &rbacv1.ClusterRoleList{ListMeta: obj.(*rbacv1.ClusterRoleList).ListMeta} - for _, item := range obj.(*rbacv1.ClusterRoleList).Items { + list := &v1.ClusterRoleList{ListMeta: obj.(*v1.ClusterRoleList).ListMeta} + for _, item := range obj.(*v1.ClusterRoleList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,58 +73,58 @@ func (c *FakeClusterRoles) List(ctx context.Context, opts v1.ListOptions) (resul } // Watch returns a watch.Interface that watches the requested clusterRoles. -func (c *FakeClusterRoles) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeClusterRoles) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(clusterrolesResource, opts)) } // Create takes the representation of a clusterRole and creates it. Returns the server's representation of the clusterRole, and an error, if there is any. -func (c *FakeClusterRoles) Create(ctx context.Context, clusterRole *rbacv1.ClusterRole, opts v1.CreateOptions) (result *rbacv1.ClusterRole, err error) { +func (c *FakeClusterRoles) Create(ctx context.Context, clusterRole *v1.ClusterRole, opts metav1.CreateOptions) (result *v1.ClusterRole, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(clusterrolesResource, clusterRole), &rbacv1.ClusterRole{}) + Invokes(testing.NewRootCreateAction(clusterrolesResource, clusterRole), &v1.ClusterRole{}) if obj == nil { return nil, err } - return obj.(*rbacv1.ClusterRole), err + return obj.(*v1.ClusterRole), err } // Update takes the representation of a clusterRole and updates it. Returns the server's representation of the clusterRole, and an error, if there is any. -func (c *FakeClusterRoles) Update(ctx context.Context, clusterRole *rbacv1.ClusterRole, opts v1.UpdateOptions) (result *rbacv1.ClusterRole, err error) { +func (c *FakeClusterRoles) Update(ctx context.Context, clusterRole *v1.ClusterRole, opts metav1.UpdateOptions) (result *v1.ClusterRole, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(clusterrolesResource, clusterRole), &rbacv1.ClusterRole{}) + Invokes(testing.NewRootUpdateAction(clusterrolesResource, clusterRole), &v1.ClusterRole{}) if obj == nil { return nil, err } - return obj.(*rbacv1.ClusterRole), err + return obj.(*v1.ClusterRole), err } // Delete takes name of the clusterRole and deletes it. Returns an error if one occurs. -func (c *FakeClusterRoles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeClusterRoles) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(clusterrolesResource, name, opts), &rbacv1.ClusterRole{}) + Invokes(testing.NewRootDeleteActionWithOptions(clusterrolesResource, name, opts), &v1.ClusterRole{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeClusterRoles) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeClusterRoles) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(clusterrolesResource, listOpts) - _, err := c.Fake.Invokes(action, &rbacv1.ClusterRoleList{}) + _, err := c.Fake.Invokes(action, &v1.ClusterRoleList{}) return err } // Patch applies the patch and returns the patched clusterRole. -func (c *FakeClusterRoles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *rbacv1.ClusterRole, err error) { +func (c *FakeClusterRoles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ClusterRole, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(clusterrolesResource, name, pt, data, subresources...), &rbacv1.ClusterRole{}) + Invokes(testing.NewRootPatchSubresourceAction(clusterrolesResource, name, pt, data, subresources...), &v1.ClusterRole{}) if obj == nil { return nil, err } - return obj.(*rbacv1.ClusterRole), err + return obj.(*v1.ClusterRole), err } // Apply takes the given apply declarative configuration, applies it and returns the applied clusterRole. -func (c *FakeClusterRoles) Apply(ctx context.Context, clusterRole *applyconfigurationsrbacv1.ClusterRoleApplyConfiguration, opts v1.ApplyOptions) (result *rbacv1.ClusterRole, err error) { +func (c *FakeClusterRoles) Apply(ctx context.Context, clusterRole *rbacv1.ClusterRoleApplyConfiguration, opts metav1.ApplyOptions) (result *v1.ClusterRole, err error) { if clusterRole == nil { return nil, fmt.Errorf("clusterRole provided to Apply must not be nil") } @@ -138,9 +137,9 @@ func (c *FakeClusterRoles) Apply(ctx context.Context, clusterRole *applyconfigur return nil, fmt.Errorf("clusterRole.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(clusterrolesResource, *name, types.ApplyPatchType, data), &rbacv1.ClusterRole{}) + Invokes(testing.NewRootPatchSubresourceAction(clusterrolesResource, *name, types.ApplyPatchType, data), &v1.ClusterRole{}) if obj == nil { return nil, err } - return obj.(*rbacv1.ClusterRole), err + return obj.(*v1.ClusterRole), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_clusterrolebinding.go b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_clusterrolebinding.go index c65399598b..d42e93e653 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_clusterrolebinding.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_clusterrolebinding.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - rbacv1 "k8s.io/api/rbac/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsrbacv1 "k8s.io/client-go/applyconfigurations/rbac/v1" + rbacv1 "k8s.io/client-go/applyconfigurations/rbac/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakeClusterRoleBindings struct { Fake *FakeRbacV1 } -var clusterrolebindingsResource = schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterrolebindings"} +var clusterrolebindingsResource = v1.SchemeGroupVersion.WithResource("clusterrolebindings") -var clusterrolebindingsKind = schema.GroupVersionKind{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "ClusterRoleBinding"} +var clusterrolebindingsKind = v1.SchemeGroupVersion.WithKind("ClusterRoleBinding") // Get takes name of the clusterRoleBinding, and returns the corresponding clusterRoleBinding object, and an error if there is any. -func (c *FakeClusterRoleBindings) Get(ctx context.Context, name string, options v1.GetOptions) (result *rbacv1.ClusterRoleBinding, err error) { +func (c *FakeClusterRoleBindings) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ClusterRoleBinding, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(clusterrolebindingsResource, name), &rbacv1.ClusterRoleBinding{}) + Invokes(testing.NewRootGetAction(clusterrolebindingsResource, name), &v1.ClusterRoleBinding{}) if obj == nil { return nil, err } - return obj.(*rbacv1.ClusterRoleBinding), err + return obj.(*v1.ClusterRoleBinding), err } // List takes label and field selectors, and returns the list of ClusterRoleBindings that match those selectors. -func (c *FakeClusterRoleBindings) List(ctx context.Context, opts v1.ListOptions) (result *rbacv1.ClusterRoleBindingList, err error) { +func (c *FakeClusterRoleBindings) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ClusterRoleBindingList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(clusterrolebindingsResource, clusterrolebindingsKind, opts), &rbacv1.ClusterRoleBindingList{}) + Invokes(testing.NewRootListAction(clusterrolebindingsResource, clusterrolebindingsKind, opts), &v1.ClusterRoleBindingList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakeClusterRoleBindings) List(ctx context.Context, opts v1.ListOptions) if label == nil { label = labels.Everything() } - list := &rbacv1.ClusterRoleBindingList{ListMeta: obj.(*rbacv1.ClusterRoleBindingList).ListMeta} - for _, item := range obj.(*rbacv1.ClusterRoleBindingList).Items { + list := &v1.ClusterRoleBindingList{ListMeta: obj.(*v1.ClusterRoleBindingList).ListMeta} + for _, item := range obj.(*v1.ClusterRoleBindingList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,58 +73,58 @@ func (c *FakeClusterRoleBindings) List(ctx context.Context, opts v1.ListOptions) } // Watch returns a watch.Interface that watches the requested clusterRoleBindings. -func (c *FakeClusterRoleBindings) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeClusterRoleBindings) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(clusterrolebindingsResource, opts)) } // Create takes the representation of a clusterRoleBinding and creates it. Returns the server's representation of the clusterRoleBinding, and an error, if there is any. -func (c *FakeClusterRoleBindings) Create(ctx context.Context, clusterRoleBinding *rbacv1.ClusterRoleBinding, opts v1.CreateOptions) (result *rbacv1.ClusterRoleBinding, err error) { +func (c *FakeClusterRoleBindings) Create(ctx context.Context, clusterRoleBinding *v1.ClusterRoleBinding, opts metav1.CreateOptions) (result *v1.ClusterRoleBinding, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(clusterrolebindingsResource, clusterRoleBinding), &rbacv1.ClusterRoleBinding{}) + Invokes(testing.NewRootCreateAction(clusterrolebindingsResource, clusterRoleBinding), &v1.ClusterRoleBinding{}) if obj == nil { return nil, err } - return obj.(*rbacv1.ClusterRoleBinding), err + return obj.(*v1.ClusterRoleBinding), err } // Update takes the representation of a clusterRoleBinding and updates it. Returns the server's representation of the clusterRoleBinding, and an error, if there is any. -func (c *FakeClusterRoleBindings) Update(ctx context.Context, clusterRoleBinding *rbacv1.ClusterRoleBinding, opts v1.UpdateOptions) (result *rbacv1.ClusterRoleBinding, err error) { +func (c *FakeClusterRoleBindings) Update(ctx context.Context, clusterRoleBinding *v1.ClusterRoleBinding, opts metav1.UpdateOptions) (result *v1.ClusterRoleBinding, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(clusterrolebindingsResource, clusterRoleBinding), &rbacv1.ClusterRoleBinding{}) + Invokes(testing.NewRootUpdateAction(clusterrolebindingsResource, clusterRoleBinding), &v1.ClusterRoleBinding{}) if obj == nil { return nil, err } - return obj.(*rbacv1.ClusterRoleBinding), err + return obj.(*v1.ClusterRoleBinding), err } // Delete takes name of the clusterRoleBinding and deletes it. Returns an error if one occurs. -func (c *FakeClusterRoleBindings) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeClusterRoleBindings) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(clusterrolebindingsResource, name, opts), &rbacv1.ClusterRoleBinding{}) + Invokes(testing.NewRootDeleteActionWithOptions(clusterrolebindingsResource, name, opts), &v1.ClusterRoleBinding{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeClusterRoleBindings) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeClusterRoleBindings) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(clusterrolebindingsResource, listOpts) - _, err := c.Fake.Invokes(action, &rbacv1.ClusterRoleBindingList{}) + _, err := c.Fake.Invokes(action, &v1.ClusterRoleBindingList{}) return err } // Patch applies the patch and returns the patched clusterRoleBinding. -func (c *FakeClusterRoleBindings) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *rbacv1.ClusterRoleBinding, err error) { +func (c *FakeClusterRoleBindings) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ClusterRoleBinding, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(clusterrolebindingsResource, name, pt, data, subresources...), &rbacv1.ClusterRoleBinding{}) + Invokes(testing.NewRootPatchSubresourceAction(clusterrolebindingsResource, name, pt, data, subresources...), &v1.ClusterRoleBinding{}) if obj == nil { return nil, err } - return obj.(*rbacv1.ClusterRoleBinding), err + return obj.(*v1.ClusterRoleBinding), err } // Apply takes the given apply declarative configuration, applies it and returns the applied clusterRoleBinding. -func (c *FakeClusterRoleBindings) Apply(ctx context.Context, clusterRoleBinding *applyconfigurationsrbacv1.ClusterRoleBindingApplyConfiguration, opts v1.ApplyOptions) (result *rbacv1.ClusterRoleBinding, err error) { +func (c *FakeClusterRoleBindings) Apply(ctx context.Context, clusterRoleBinding *rbacv1.ClusterRoleBindingApplyConfiguration, opts metav1.ApplyOptions) (result *v1.ClusterRoleBinding, err error) { if clusterRoleBinding == nil { return nil, fmt.Errorf("clusterRoleBinding provided to Apply must not be nil") } @@ -138,9 +137,9 @@ func (c *FakeClusterRoleBindings) Apply(ctx context.Context, clusterRoleBinding return nil, fmt.Errorf("clusterRoleBinding.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(clusterrolebindingsResource, *name, types.ApplyPatchType, data), &rbacv1.ClusterRoleBinding{}) + Invokes(testing.NewRootPatchSubresourceAction(clusterrolebindingsResource, *name, types.ApplyPatchType, data), &v1.ClusterRoleBinding{}) if obj == nil { return nil, err } - return obj.(*rbacv1.ClusterRoleBinding), err + return obj.(*v1.ClusterRoleBinding), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_role.go b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_role.go index 4a70d0c353..a3bc5da663 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_role.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_role.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - rbacv1 "k8s.io/api/rbac/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsrbacv1 "k8s.io/client-go/applyconfigurations/rbac/v1" + rbacv1 "k8s.io/client-go/applyconfigurations/rbac/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeRoles struct { ns string } -var rolesResource = schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "roles"} +var rolesResource = v1.SchemeGroupVersion.WithResource("roles") -var rolesKind = schema.GroupVersionKind{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "Role"} +var rolesKind = v1.SchemeGroupVersion.WithKind("Role") // Get takes name of the role, and returns the corresponding role object, and an error if there is any. -func (c *FakeRoles) Get(ctx context.Context, name string, options v1.GetOptions) (result *rbacv1.Role, err error) { +func (c *FakeRoles) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Role, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(rolesResource, c.ns, name), &rbacv1.Role{}) + Invokes(testing.NewGetAction(rolesResource, c.ns, name), &v1.Role{}) if obj == nil { return nil, err } - return obj.(*rbacv1.Role), err + return obj.(*v1.Role), err } // List takes label and field selectors, and returns the list of Roles that match those selectors. -func (c *FakeRoles) List(ctx context.Context, opts v1.ListOptions) (result *rbacv1.RoleList, err error) { +func (c *FakeRoles) List(ctx context.Context, opts metav1.ListOptions) (result *v1.RoleList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(rolesResource, rolesKind, c.ns, opts), &rbacv1.RoleList{}) + Invokes(testing.NewListAction(rolesResource, rolesKind, c.ns, opts), &v1.RoleList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeRoles) List(ctx context.Context, opts v1.ListOptions) (result *rbac if label == nil { label = labels.Everything() } - list := &rbacv1.RoleList{ListMeta: obj.(*rbacv1.RoleList).ListMeta} - for _, item := range obj.(*rbacv1.RoleList).Items { + list := &v1.RoleList{ListMeta: obj.(*v1.RoleList).ListMeta} + for _, item := range obj.(*v1.RoleList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,63 +76,63 @@ func (c *FakeRoles) List(ctx context.Context, opts v1.ListOptions) (result *rbac } // Watch returns a watch.Interface that watches the requested roles. -func (c *FakeRoles) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeRoles) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(rolesResource, c.ns, opts)) } // Create takes the representation of a role and creates it. Returns the server's representation of the role, and an error, if there is any. -func (c *FakeRoles) Create(ctx context.Context, role *rbacv1.Role, opts v1.CreateOptions) (result *rbacv1.Role, err error) { +func (c *FakeRoles) Create(ctx context.Context, role *v1.Role, opts metav1.CreateOptions) (result *v1.Role, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(rolesResource, c.ns, role), &rbacv1.Role{}) + Invokes(testing.NewCreateAction(rolesResource, c.ns, role), &v1.Role{}) if obj == nil { return nil, err } - return obj.(*rbacv1.Role), err + return obj.(*v1.Role), err } // Update takes the representation of a role and updates it. Returns the server's representation of the role, and an error, if there is any. -func (c *FakeRoles) Update(ctx context.Context, role *rbacv1.Role, opts v1.UpdateOptions) (result *rbacv1.Role, err error) { +func (c *FakeRoles) Update(ctx context.Context, role *v1.Role, opts metav1.UpdateOptions) (result *v1.Role, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(rolesResource, c.ns, role), &rbacv1.Role{}) + Invokes(testing.NewUpdateAction(rolesResource, c.ns, role), &v1.Role{}) if obj == nil { return nil, err } - return obj.(*rbacv1.Role), err + return obj.(*v1.Role), err } // Delete takes name of the role and deletes it. Returns an error if one occurs. -func (c *FakeRoles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeRoles) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(rolesResource, c.ns, name, opts), &rbacv1.Role{}) + Invokes(testing.NewDeleteActionWithOptions(rolesResource, c.ns, name, opts), &v1.Role{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeRoles) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeRoles) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(rolesResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &rbacv1.RoleList{}) + _, err := c.Fake.Invokes(action, &v1.RoleList{}) return err } // Patch applies the patch and returns the patched role. -func (c *FakeRoles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *rbacv1.Role, err error) { +func (c *FakeRoles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Role, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(rolesResource, c.ns, name, pt, data, subresources...), &rbacv1.Role{}) + Invokes(testing.NewPatchSubresourceAction(rolesResource, c.ns, name, pt, data, subresources...), &v1.Role{}) if obj == nil { return nil, err } - return obj.(*rbacv1.Role), err + return obj.(*v1.Role), err } // Apply takes the given apply declarative configuration, applies it and returns the applied role. -func (c *FakeRoles) Apply(ctx context.Context, role *applyconfigurationsrbacv1.RoleApplyConfiguration, opts v1.ApplyOptions) (result *rbacv1.Role, err error) { +func (c *FakeRoles) Apply(ctx context.Context, role *rbacv1.RoleApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Role, err error) { if role == nil { return nil, fmt.Errorf("role provided to Apply must not be nil") } @@ -146,10 +145,10 @@ func (c *FakeRoles) Apply(ctx context.Context, role *applyconfigurationsrbacv1.R return nil, fmt.Errorf("role.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(rolesResource, c.ns, *name, types.ApplyPatchType, data), &rbacv1.Role{}) + Invokes(testing.NewPatchSubresourceAction(rolesResource, c.ns, *name, types.ApplyPatchType, data), &v1.Role{}) if obj == nil { return nil, err } - return obj.(*rbacv1.Role), err + return obj.(*v1.Role), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_rolebinding.go b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_rolebinding.go index 0db37dd57b..eeb37e9db3 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_rolebinding.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1/fake/fake_rolebinding.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - rbacv1 "k8s.io/api/rbac/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsrbacv1 "k8s.io/client-go/applyconfigurations/rbac/v1" + rbacv1 "k8s.io/client-go/applyconfigurations/rbac/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeRoleBindings struct { ns string } -var rolebindingsResource = schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "rolebindings"} +var rolebindingsResource = v1.SchemeGroupVersion.WithResource("rolebindings") -var rolebindingsKind = schema.GroupVersionKind{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "RoleBinding"} +var rolebindingsKind = v1.SchemeGroupVersion.WithKind("RoleBinding") // Get takes name of the roleBinding, and returns the corresponding roleBinding object, and an error if there is any. -func (c *FakeRoleBindings) Get(ctx context.Context, name string, options v1.GetOptions) (result *rbacv1.RoleBinding, err error) { +func (c *FakeRoleBindings) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.RoleBinding, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(rolebindingsResource, c.ns, name), &rbacv1.RoleBinding{}) + Invokes(testing.NewGetAction(rolebindingsResource, c.ns, name), &v1.RoleBinding{}) if obj == nil { return nil, err } - return obj.(*rbacv1.RoleBinding), err + return obj.(*v1.RoleBinding), err } // List takes label and field selectors, and returns the list of RoleBindings that match those selectors. -func (c *FakeRoleBindings) List(ctx context.Context, opts v1.ListOptions) (result *rbacv1.RoleBindingList, err error) { +func (c *FakeRoleBindings) List(ctx context.Context, opts metav1.ListOptions) (result *v1.RoleBindingList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(rolebindingsResource, rolebindingsKind, c.ns, opts), &rbacv1.RoleBindingList{}) + Invokes(testing.NewListAction(rolebindingsResource, rolebindingsKind, c.ns, opts), &v1.RoleBindingList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeRoleBindings) List(ctx context.Context, opts v1.ListOptions) (resul if label == nil { label = labels.Everything() } - list := &rbacv1.RoleBindingList{ListMeta: obj.(*rbacv1.RoleBindingList).ListMeta} - for _, item := range obj.(*rbacv1.RoleBindingList).Items { + list := &v1.RoleBindingList{ListMeta: obj.(*v1.RoleBindingList).ListMeta} + for _, item := range obj.(*v1.RoleBindingList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,63 +76,63 @@ func (c *FakeRoleBindings) List(ctx context.Context, opts v1.ListOptions) (resul } // Watch returns a watch.Interface that watches the requested roleBindings. -func (c *FakeRoleBindings) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeRoleBindings) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(rolebindingsResource, c.ns, opts)) } // Create takes the representation of a roleBinding and creates it. Returns the server's representation of the roleBinding, and an error, if there is any. -func (c *FakeRoleBindings) Create(ctx context.Context, roleBinding *rbacv1.RoleBinding, opts v1.CreateOptions) (result *rbacv1.RoleBinding, err error) { +func (c *FakeRoleBindings) Create(ctx context.Context, roleBinding *v1.RoleBinding, opts metav1.CreateOptions) (result *v1.RoleBinding, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(rolebindingsResource, c.ns, roleBinding), &rbacv1.RoleBinding{}) + Invokes(testing.NewCreateAction(rolebindingsResource, c.ns, roleBinding), &v1.RoleBinding{}) if obj == nil { return nil, err } - return obj.(*rbacv1.RoleBinding), err + return obj.(*v1.RoleBinding), err } // Update takes the representation of a roleBinding and updates it. Returns the server's representation of the roleBinding, and an error, if there is any. -func (c *FakeRoleBindings) Update(ctx context.Context, roleBinding *rbacv1.RoleBinding, opts v1.UpdateOptions) (result *rbacv1.RoleBinding, err error) { +func (c *FakeRoleBindings) Update(ctx context.Context, roleBinding *v1.RoleBinding, opts metav1.UpdateOptions) (result *v1.RoleBinding, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(rolebindingsResource, c.ns, roleBinding), &rbacv1.RoleBinding{}) + Invokes(testing.NewUpdateAction(rolebindingsResource, c.ns, roleBinding), &v1.RoleBinding{}) if obj == nil { return nil, err } - return obj.(*rbacv1.RoleBinding), err + return obj.(*v1.RoleBinding), err } // Delete takes name of the roleBinding and deletes it. Returns an error if one occurs. -func (c *FakeRoleBindings) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeRoleBindings) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(rolebindingsResource, c.ns, name, opts), &rbacv1.RoleBinding{}) + Invokes(testing.NewDeleteActionWithOptions(rolebindingsResource, c.ns, name, opts), &v1.RoleBinding{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeRoleBindings) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeRoleBindings) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(rolebindingsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &rbacv1.RoleBindingList{}) + _, err := c.Fake.Invokes(action, &v1.RoleBindingList{}) return err } // Patch applies the patch and returns the patched roleBinding. -func (c *FakeRoleBindings) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *rbacv1.RoleBinding, err error) { +func (c *FakeRoleBindings) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RoleBinding, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(rolebindingsResource, c.ns, name, pt, data, subresources...), &rbacv1.RoleBinding{}) + Invokes(testing.NewPatchSubresourceAction(rolebindingsResource, c.ns, name, pt, data, subresources...), &v1.RoleBinding{}) if obj == nil { return nil, err } - return obj.(*rbacv1.RoleBinding), err + return obj.(*v1.RoleBinding), err } // Apply takes the given apply declarative configuration, applies it and returns the applied roleBinding. -func (c *FakeRoleBindings) Apply(ctx context.Context, roleBinding *applyconfigurationsrbacv1.RoleBindingApplyConfiguration, opts v1.ApplyOptions) (result *rbacv1.RoleBinding, err error) { +func (c *FakeRoleBindings) Apply(ctx context.Context, roleBinding *rbacv1.RoleBindingApplyConfiguration, opts metav1.ApplyOptions) (result *v1.RoleBinding, err error) { if roleBinding == nil { return nil, fmt.Errorf("roleBinding provided to Apply must not be nil") } @@ -146,10 +145,10 @@ func (c *FakeRoleBindings) Apply(ctx context.Context, roleBinding *applyconfigur return nil, fmt.Errorf("roleBinding.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(rolebindingsResource, c.ns, *name, types.ApplyPatchType, data), &rbacv1.RoleBinding{}) + Invokes(testing.NewPatchSubresourceAction(rolebindingsResource, c.ns, *name, types.ApplyPatchType, data), &v1.RoleBinding{}) if obj == nil { return nil, err } - return obj.(*rbacv1.RoleBinding), err + return obj.(*v1.RoleBinding), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_clusterrole.go b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_clusterrole.go index 7e8e3a9b8a..534a1990f5 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_clusterrole.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_clusterrole.go @@ -26,7 +26,6 @@ import ( v1alpha1 "k8s.io/api/rbac/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" rbacv1alpha1 "k8s.io/client-go/applyconfigurations/rbac/v1alpha1" @@ -38,9 +37,9 @@ type FakeClusterRoles struct { Fake *FakeRbacV1alpha1 } -var clusterrolesResource = schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Resource: "clusterroles"} +var clusterrolesResource = v1alpha1.SchemeGroupVersion.WithResource("clusterroles") -var clusterrolesKind = schema.GroupVersionKind{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Kind: "ClusterRole"} +var clusterrolesKind = v1alpha1.SchemeGroupVersion.WithKind("ClusterRole") // Get takes name of the clusterRole, and returns the corresponding clusterRole object, and an error if there is any. func (c *FakeClusterRoles) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterRole, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_clusterrolebinding.go b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_clusterrolebinding.go index 5c5e632789..0a4359392d 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_clusterrolebinding.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_clusterrolebinding.go @@ -26,7 +26,6 @@ import ( v1alpha1 "k8s.io/api/rbac/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" rbacv1alpha1 "k8s.io/client-go/applyconfigurations/rbac/v1alpha1" @@ -38,9 +37,9 @@ type FakeClusterRoleBindings struct { Fake *FakeRbacV1alpha1 } -var clusterrolebindingsResource = schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Resource: "clusterrolebindings"} +var clusterrolebindingsResource = v1alpha1.SchemeGroupVersion.WithResource("clusterrolebindings") -var clusterrolebindingsKind = schema.GroupVersionKind{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Kind: "ClusterRoleBinding"} +var clusterrolebindingsKind = v1alpha1.SchemeGroupVersion.WithKind("ClusterRoleBinding") // Get takes name of the clusterRoleBinding, and returns the corresponding clusterRoleBinding object, and an error if there is any. func (c *FakeClusterRoleBindings) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterRoleBinding, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_role.go b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_role.go index cec3f099dc..a0e28348ae 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_role.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_role.go @@ -26,7 +26,6 @@ import ( v1alpha1 "k8s.io/api/rbac/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" rbacv1alpha1 "k8s.io/client-go/applyconfigurations/rbac/v1alpha1" @@ -39,9 +38,9 @@ type FakeRoles struct { ns string } -var rolesResource = schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Resource: "roles"} +var rolesResource = v1alpha1.SchemeGroupVersion.WithResource("roles") -var rolesKind = schema.GroupVersionKind{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Kind: "Role"} +var rolesKind = v1alpha1.SchemeGroupVersion.WithKind("Role") // Get takes name of the role, and returns the corresponding role object, and an error if there is any. func (c *FakeRoles) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.Role, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_rolebinding.go b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_rolebinding.go index 2d66494fdc..76649f5c2b 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_rolebinding.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1alpha1/fake/fake_rolebinding.go @@ -26,7 +26,6 @@ import ( v1alpha1 "k8s.io/api/rbac/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" rbacv1alpha1 "k8s.io/client-go/applyconfigurations/rbac/v1alpha1" @@ -39,9 +38,9 @@ type FakeRoleBindings struct { ns string } -var rolebindingsResource = schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Resource: "rolebindings"} +var rolebindingsResource = v1alpha1.SchemeGroupVersion.WithResource("rolebindings") -var rolebindingsKind = schema.GroupVersionKind{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Kind: "RoleBinding"} +var rolebindingsKind = v1alpha1.SchemeGroupVersion.WithKind("RoleBinding") // Get takes name of the roleBinding, and returns the corresponding roleBinding object, and an error if there is any. func (c *FakeRoleBindings) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.RoleBinding, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_clusterrole.go b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_clusterrole.go index 2b4f60054e..2a94a4315e 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_clusterrole.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_clusterrole.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/rbac/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" rbacv1beta1 "k8s.io/client-go/applyconfigurations/rbac/v1beta1" @@ -38,9 +37,9 @@ type FakeClusterRoles struct { Fake *FakeRbacV1beta1 } -var clusterrolesResource = schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Resource: "clusterroles"} +var clusterrolesResource = v1beta1.SchemeGroupVersion.WithResource("clusterroles") -var clusterrolesKind = schema.GroupVersionKind{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Kind: "ClusterRole"} +var clusterrolesKind = v1beta1.SchemeGroupVersion.WithKind("ClusterRole") // Get takes name of the clusterRole, and returns the corresponding clusterRole object, and an error if there is any. func (c *FakeClusterRoles) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ClusterRole, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_clusterrolebinding.go b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_clusterrolebinding.go index 379261ec86..c9fd7c0cdd 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_clusterrolebinding.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_clusterrolebinding.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/rbac/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" rbacv1beta1 "k8s.io/client-go/applyconfigurations/rbac/v1beta1" @@ -38,9 +37,9 @@ type FakeClusterRoleBindings struct { Fake *FakeRbacV1beta1 } -var clusterrolebindingsResource = schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Resource: "clusterrolebindings"} +var clusterrolebindingsResource = v1beta1.SchemeGroupVersion.WithResource("clusterrolebindings") -var clusterrolebindingsKind = schema.GroupVersionKind{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Kind: "ClusterRoleBinding"} +var clusterrolebindingsKind = v1beta1.SchemeGroupVersion.WithKind("ClusterRoleBinding") // Get takes name of the clusterRoleBinding, and returns the corresponding clusterRoleBinding object, and an error if there is any. func (c *FakeClusterRoleBindings) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ClusterRoleBinding, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_role.go b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_role.go index 44df9128a0..4158cf1d55 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_role.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_role.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/rbac/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" rbacv1beta1 "k8s.io/client-go/applyconfigurations/rbac/v1beta1" @@ -39,9 +38,9 @@ type FakeRoles struct { ns string } -var rolesResource = schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Resource: "roles"} +var rolesResource = v1beta1.SchemeGroupVersion.WithResource("roles") -var rolesKind = schema.GroupVersionKind{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Kind: "Role"} +var rolesKind = v1beta1.SchemeGroupVersion.WithKind("Role") // Get takes name of the role, and returns the corresponding role object, and an error if there is any. func (c *FakeRoles) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Role, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_rolebinding.go b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_rolebinding.go index 5e90e6dbd1..4616f0fd10 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_rolebinding.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/rbac/v1beta1/fake/fake_rolebinding.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/rbac/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" rbacv1beta1 "k8s.io/client-go/applyconfigurations/rbac/v1beta1" @@ -39,9 +38,9 @@ type FakeRoleBindings struct { ns string } -var rolebindingsResource = schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Resource: "rolebindings"} +var rolebindingsResource = v1beta1.SchemeGroupVersion.WithResource("rolebindings") -var rolebindingsKind = schema.GroupVersionKind{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Kind: "RoleBinding"} +var rolebindingsKind = v1beta1.SchemeGroupVersion.WithKind("RoleBinding") // Get takes name of the roleBinding, and returns the corresponding roleBinding object, and an error if there is any. func (c *FakeRoleBindings) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.RoleBinding, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/fake_podscheduling.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/fake_podscheduling.go deleted file mode 100644 index 7b4e2a5d5a..0000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/fake_podscheduling.go +++ /dev/null @@ -1,190 +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 - -import ( - "context" - json "encoding/json" - "fmt" - - v1alpha1 "k8s.io/api/resource/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - resourcev1alpha1 "k8s.io/client-go/applyconfigurations/resource/v1alpha1" - testing "k8s.io/client-go/testing" -) - -// FakePodSchedulings implements PodSchedulingInterface -type FakePodSchedulings struct { - Fake *FakeResourceV1alpha1 - ns string -} - -var podschedulingsResource = schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1alpha1", Resource: "podschedulings"} - -var podschedulingsKind = schema.GroupVersionKind{Group: "resource.k8s.io", Version: "v1alpha1", Kind: "PodScheduling"} - -// Get takes name of the podScheduling, and returns the corresponding podScheduling object, and an error if there is any. -func (c *FakePodSchedulings) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.PodScheduling, err error) { - obj, err := c.Fake. - Invokes(testing.NewGetAction(podschedulingsResource, c.ns, name), &v1alpha1.PodScheduling{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.PodScheduling), err -} - -// List takes label and field selectors, and returns the list of PodSchedulings that match those selectors. -func (c *FakePodSchedulings) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.PodSchedulingList, err error) { - obj, err := c.Fake. - Invokes(testing.NewListAction(podschedulingsResource, podschedulingsKind, c.ns, opts), &v1alpha1.PodSchedulingList{}) - - if obj == nil { - return nil, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1alpha1.PodSchedulingList{ListMeta: obj.(*v1alpha1.PodSchedulingList).ListMeta} - for _, item := range obj.(*v1alpha1.PodSchedulingList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// Watch returns a watch.Interface that watches the requested podSchedulings. -func (c *FakePodSchedulings) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - return c.Fake. - InvokesWatch(testing.NewWatchAction(podschedulingsResource, c.ns, opts)) - -} - -// Create takes the representation of a podScheduling and creates it. Returns the server's representation of the podScheduling, and an error, if there is any. -func (c *FakePodSchedulings) Create(ctx context.Context, podScheduling *v1alpha1.PodScheduling, opts v1.CreateOptions) (result *v1alpha1.PodScheduling, err error) { - obj, err := c.Fake. - Invokes(testing.NewCreateAction(podschedulingsResource, c.ns, podScheduling), &v1alpha1.PodScheduling{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.PodScheduling), err -} - -// Update takes the representation of a podScheduling and updates it. Returns the server's representation of the podScheduling, and an error, if there is any. -func (c *FakePodSchedulings) Update(ctx context.Context, podScheduling *v1alpha1.PodScheduling, opts v1.UpdateOptions) (result *v1alpha1.PodScheduling, err error) { - obj, err := c.Fake. - Invokes(testing.NewUpdateAction(podschedulingsResource, c.ns, podScheduling), &v1alpha1.PodScheduling{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.PodScheduling), 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 *FakePodSchedulings) UpdateStatus(ctx context.Context, podScheduling *v1alpha1.PodScheduling, opts v1.UpdateOptions) (*v1alpha1.PodScheduling, error) { - obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(podschedulingsResource, "status", c.ns, podScheduling), &v1alpha1.PodScheduling{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.PodScheduling), err -} - -// Delete takes name of the podScheduling and deletes it. Returns an error if one occurs. -func (c *FakePodSchedulings) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(podschedulingsResource, c.ns, name, opts), &v1alpha1.PodScheduling{}) - - return err -} - -// DeleteCollection deletes a collection of objects. -func (c *FakePodSchedulings) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewDeleteCollectionAction(podschedulingsResource, c.ns, listOpts) - - _, err := c.Fake.Invokes(action, &v1alpha1.PodSchedulingList{}) - return err -} - -// Patch applies the patch and returns the patched podScheduling. -func (c *FakePodSchedulings) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.PodScheduling, err error) { - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(podschedulingsResource, c.ns, name, pt, data, subresources...), &v1alpha1.PodScheduling{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.PodScheduling), err -} - -// Apply takes the given apply declarative configuration, applies it and returns the applied podScheduling. -func (c *FakePodSchedulings) Apply(ctx context.Context, podScheduling *resourcev1alpha1.PodSchedulingApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.PodScheduling, err error) { - if podScheduling == nil { - return nil, fmt.Errorf("podScheduling provided to Apply must not be nil") - } - data, err := json.Marshal(podScheduling) - if err != nil { - return nil, err - } - name := podScheduling.Name - if name == nil { - return nil, fmt.Errorf("podScheduling.Name must be provided to Apply") - } - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(podschedulingsResource, c.ns, *name, types.ApplyPatchType, data), &v1alpha1.PodScheduling{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.PodScheduling), err -} - -// ApplyStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakePodSchedulings) ApplyStatus(ctx context.Context, podScheduling *resourcev1alpha1.PodSchedulingApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.PodScheduling, err error) { - if podScheduling == nil { - return nil, fmt.Errorf("podScheduling provided to Apply must not be nil") - } - data, err := json.Marshal(podScheduling) - if err != nil { - return nil, err - } - name := podScheduling.Name - if name == nil { - return nil, fmt.Errorf("podScheduling.Name must be provided to Apply") - } - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(podschedulingsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1alpha1.PodScheduling{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.PodScheduling), err -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/podscheduling.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/podscheduling.go deleted file mode 100644 index e163a84561..0000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/podscheduling.go +++ /dev/null @@ -1,256 +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 v1alpha1 - -import ( - "context" - json "encoding/json" - "fmt" - "time" - - v1alpha1 "k8s.io/api/resource/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - resourcev1alpha1 "k8s.io/client-go/applyconfigurations/resource/v1alpha1" - scheme "k8s.io/client-go/kubernetes/scheme" - rest "k8s.io/client-go/rest" -) - -// PodSchedulingsGetter has a method to return a PodSchedulingInterface. -// A group's client should implement this interface. -type PodSchedulingsGetter interface { - PodSchedulings(namespace string) PodSchedulingInterface -} - -// PodSchedulingInterface has methods to work with PodScheduling resources. -type PodSchedulingInterface interface { - Create(ctx context.Context, podScheduling *v1alpha1.PodScheduling, opts v1.CreateOptions) (*v1alpha1.PodScheduling, error) - Update(ctx context.Context, podScheduling *v1alpha1.PodScheduling, opts v1.UpdateOptions) (*v1alpha1.PodScheduling, error) - UpdateStatus(ctx context.Context, podScheduling *v1alpha1.PodScheduling, opts v1.UpdateOptions) (*v1alpha1.PodScheduling, error) - Delete(ctx context.Context, name string, opts v1.DeleteOptions) error - DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.PodScheduling, error) - List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.PodSchedulingList, error) - Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.PodScheduling, err error) - Apply(ctx context.Context, podScheduling *resourcev1alpha1.PodSchedulingApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.PodScheduling, err error) - ApplyStatus(ctx context.Context, podScheduling *resourcev1alpha1.PodSchedulingApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.PodScheduling, err error) - PodSchedulingExpansion -} - -// podSchedulings implements PodSchedulingInterface -type podSchedulings struct { - client rest.Interface - ns string -} - -// newPodSchedulings returns a PodSchedulings -func newPodSchedulings(c *ResourceV1alpha1Client, namespace string) *podSchedulings { - return &podSchedulings{ - client: c.RESTClient(), - ns: namespace, - } -} - -// Get takes name of the podScheduling, and returns the corresponding podScheduling object, and an error if there is any. -func (c *podSchedulings) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.PodScheduling, err error) { - result = &v1alpha1.PodScheduling{} - err = c.client.Get(). - Namespace(c.ns). - Resource("podschedulings"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(ctx). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of PodSchedulings that match those selectors. -func (c *podSchedulings) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.PodSchedulingList, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &v1alpha1.PodSchedulingList{} - err = c.client.Get(). - Namespace(c.ns). - Resource("podschedulings"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Do(ctx). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested podSchedulings. -func (c *podSchedulings) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - Namespace(c.ns). - Resource("podschedulings"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Watch(ctx) -} - -// Create takes the representation of a podScheduling and creates it. Returns the server's representation of the podScheduling, and an error, if there is any. -func (c *podSchedulings) Create(ctx context.Context, podScheduling *v1alpha1.PodScheduling, opts v1.CreateOptions) (result *v1alpha1.PodScheduling, err error) { - result = &v1alpha1.PodScheduling{} - err = c.client.Post(). - Namespace(c.ns). - Resource("podschedulings"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(podScheduling). - Do(ctx). - Into(result) - return -} - -// Update takes the representation of a podScheduling and updates it. Returns the server's representation of the podScheduling, and an error, if there is any. -func (c *podSchedulings) Update(ctx context.Context, podScheduling *v1alpha1.PodScheduling, opts v1.UpdateOptions) (result *v1alpha1.PodScheduling, err error) { - result = &v1alpha1.PodScheduling{} - err = c.client.Put(). - Namespace(c.ns). - Resource("podschedulings"). - Name(podScheduling.Name). - VersionedParams(&opts, scheme.ParameterCodec). - Body(podScheduling). - Do(ctx). - Into(result) - return -} - -// UpdateStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *podSchedulings) UpdateStatus(ctx context.Context, podScheduling *v1alpha1.PodScheduling, opts v1.UpdateOptions) (result *v1alpha1.PodScheduling, err error) { - result = &v1alpha1.PodScheduling{} - err = c.client.Put(). - Namespace(c.ns). - Resource("podschedulings"). - Name(podScheduling.Name). - SubResource("status"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(podScheduling). - Do(ctx). - Into(result) - return -} - -// Delete takes name of the podScheduling and deletes it. Returns an error if one occurs. -func (c *podSchedulings) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - return c.client.Delete(). - Namespace(c.ns). - Resource("podschedulings"). - Name(name). - Body(&opts). - Do(ctx). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *podSchedulings) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - var timeout time.Duration - if listOpts.TimeoutSeconds != nil { - timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - Namespace(c.ns). - Resource("podschedulings"). - VersionedParams(&listOpts, scheme.ParameterCodec). - Timeout(timeout). - Body(&opts). - Do(ctx). - Error() -} - -// Patch applies the patch and returns the patched podScheduling. -func (c *podSchedulings) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.PodScheduling, err error) { - result = &v1alpha1.PodScheduling{} - err = c.client.Patch(pt). - Namespace(c.ns). - Resource("podschedulings"). - Name(name). - SubResource(subresources...). - VersionedParams(&opts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} - -// Apply takes the given apply declarative configuration, applies it and returns the applied podScheduling. -func (c *podSchedulings) Apply(ctx context.Context, podScheduling *resourcev1alpha1.PodSchedulingApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.PodScheduling, err error) { - if podScheduling == nil { - return nil, fmt.Errorf("podScheduling provided to Apply must not be nil") - } - patchOpts := opts.ToPatchOptions() - data, err := json.Marshal(podScheduling) - if err != nil { - return nil, err - } - name := podScheduling.Name - if name == nil { - return nil, fmt.Errorf("podScheduling.Name must be provided to Apply") - } - result = &v1alpha1.PodScheduling{} - err = c.client.Patch(types.ApplyPatchType). - Namespace(c.ns). - Resource("podschedulings"). - Name(*name). - VersionedParams(&patchOpts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} - -// ApplyStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *podSchedulings) ApplyStatus(ctx context.Context, podScheduling *resourcev1alpha1.PodSchedulingApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.PodScheduling, err error) { - if podScheduling == nil { - return nil, fmt.Errorf("podScheduling provided to Apply must not be nil") - } - patchOpts := opts.ToPatchOptions() - data, err := json.Marshal(podScheduling) - if err != nil { - return nil, err - } - - name := podScheduling.Name - if name == nil { - return nil, fmt.Errorf("podScheduling.Name must be provided to Apply") - } - - result = &v1alpha1.PodScheduling{} - err = c.client.Patch(types.ApplyPatchType). - Namespace(c.ns). - Resource("podschedulings"). - Name(*name). - SubResource("status"). - VersionedParams(&patchOpts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/doc.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/doc.go new file mode 100644 index 0000000000..baaf2d9853 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/doc.go @@ -0,0 +1,20 @@ +/* +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. + +// This package has the automatically generated typed clients. +package v1alpha2 diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/doc.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/doc.go new file mode 100644 index 0000000000..16f4439906 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/doc.go @@ -0,0 +1,20 @@ +/* +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 has the automatically generated clients. +package fake diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_podschedulingcontext.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_podschedulingcontext.go new file mode 100644 index 0000000000..54882f8175 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_podschedulingcontext.go @@ -0,0 +1,189 @@ +/* +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 + +import ( + "context" + json "encoding/json" + "fmt" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" + testing "k8s.io/client-go/testing" +) + +// FakePodSchedulingContexts implements PodSchedulingContextInterface +type FakePodSchedulingContexts struct { + Fake *FakeResourceV1alpha2 + ns string +} + +var podschedulingcontextsResource = v1alpha2.SchemeGroupVersion.WithResource("podschedulingcontexts") + +var podschedulingcontextsKind = v1alpha2.SchemeGroupVersion.WithKind("PodSchedulingContext") + +// Get takes name of the podSchedulingContext, and returns the corresponding podSchedulingContext object, and an error if there is any. +func (c *FakePodSchedulingContexts) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.PodSchedulingContext, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(podschedulingcontextsResource, c.ns, name), &v1alpha2.PodSchedulingContext{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.PodSchedulingContext), err +} + +// List takes label and field selectors, and returns the list of PodSchedulingContexts that match those selectors. +func (c *FakePodSchedulingContexts) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.PodSchedulingContextList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(podschedulingcontextsResource, podschedulingcontextsKind, c.ns, opts), &v1alpha2.PodSchedulingContextList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha2.PodSchedulingContextList{ListMeta: obj.(*v1alpha2.PodSchedulingContextList).ListMeta} + for _, item := range obj.(*v1alpha2.PodSchedulingContextList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested podSchedulingContexts. +func (c *FakePodSchedulingContexts) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(podschedulingcontextsResource, c.ns, opts)) + +} + +// Create takes the representation of a podSchedulingContext and creates it. Returns the server's representation of the podSchedulingContext, and an error, if there is any. +func (c *FakePodSchedulingContexts) Create(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.CreateOptions) (result *v1alpha2.PodSchedulingContext, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(podschedulingcontextsResource, c.ns, podSchedulingContext), &v1alpha2.PodSchedulingContext{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.PodSchedulingContext), err +} + +// Update takes the representation of a podSchedulingContext and updates it. Returns the server's representation of the podSchedulingContext, and an error, if there is any. +func (c *FakePodSchedulingContexts) Update(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.UpdateOptions) (result *v1alpha2.PodSchedulingContext, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(podschedulingcontextsResource, c.ns, podSchedulingContext), &v1alpha2.PodSchedulingContext{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.PodSchedulingContext), 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 *FakePodSchedulingContexts) UpdateStatus(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.UpdateOptions) (*v1alpha2.PodSchedulingContext, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(podschedulingcontextsResource, "status", c.ns, podSchedulingContext), &v1alpha2.PodSchedulingContext{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.PodSchedulingContext), err +} + +// Delete takes name of the podSchedulingContext and deletes it. Returns an error if one occurs. +func (c *FakePodSchedulingContexts) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(podschedulingcontextsResource, c.ns, name, opts), &v1alpha2.PodSchedulingContext{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakePodSchedulingContexts) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(podschedulingcontextsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha2.PodSchedulingContextList{}) + return err +} + +// Patch applies the patch and returns the patched podSchedulingContext. +func (c *FakePodSchedulingContexts) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.PodSchedulingContext, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(podschedulingcontextsResource, c.ns, name, pt, data, subresources...), &v1alpha2.PodSchedulingContext{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.PodSchedulingContext), err +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied podSchedulingContext. +func (c *FakePodSchedulingContexts) Apply(ctx context.Context, podSchedulingContext *resourcev1alpha2.PodSchedulingContextApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.PodSchedulingContext, err error) { + if podSchedulingContext == nil { + return nil, fmt.Errorf("podSchedulingContext provided to Apply must not be nil") + } + data, err := json.Marshal(podSchedulingContext) + if err != nil { + return nil, err + } + name := podSchedulingContext.Name + if name == nil { + return nil, fmt.Errorf("podSchedulingContext.Name must be provided to Apply") + } + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(podschedulingcontextsResource, c.ns, *name, types.ApplyPatchType, data), &v1alpha2.PodSchedulingContext{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.PodSchedulingContext), err +} + +// ApplyStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). +func (c *FakePodSchedulingContexts) ApplyStatus(ctx context.Context, podSchedulingContext *resourcev1alpha2.PodSchedulingContextApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.PodSchedulingContext, err error) { + if podSchedulingContext == nil { + return nil, fmt.Errorf("podSchedulingContext provided to Apply must not be nil") + } + data, err := json.Marshal(podSchedulingContext) + if err != nil { + return nil, err + } + name := podSchedulingContext.Name + if name == nil { + return nil, fmt.Errorf("podSchedulingContext.Name must be provided to Apply") + } + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(podschedulingcontextsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1alpha2.PodSchedulingContext{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha2.PodSchedulingContext), err +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/fake_resource_client.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resource_client.go similarity index 63% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/fake_resource_client.go rename to vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resource_client.go index c4776ee54f..2053877320 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/fake_resource_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resource_client.go @@ -19,34 +19,34 @@ limitations under the License. package fake import ( - v1alpha1 "k8s.io/client-go/kubernetes/typed/resource/v1alpha1" + v1alpha2 "k8s.io/client-go/kubernetes/typed/resource/v1alpha2" rest "k8s.io/client-go/rest" testing "k8s.io/client-go/testing" ) -type FakeResourceV1alpha1 struct { +type FakeResourceV1alpha2 struct { *testing.Fake } -func (c *FakeResourceV1alpha1) PodSchedulings(namespace string) v1alpha1.PodSchedulingInterface { - return &FakePodSchedulings{c, namespace} +func (c *FakeResourceV1alpha2) PodSchedulingContexts(namespace string) v1alpha2.PodSchedulingContextInterface { + return &FakePodSchedulingContexts{c, namespace} } -func (c *FakeResourceV1alpha1) ResourceClaims(namespace string) v1alpha1.ResourceClaimInterface { +func (c *FakeResourceV1alpha2) ResourceClaims(namespace string) v1alpha2.ResourceClaimInterface { return &FakeResourceClaims{c, namespace} } -func (c *FakeResourceV1alpha1) ResourceClaimTemplates(namespace string) v1alpha1.ResourceClaimTemplateInterface { +func (c *FakeResourceV1alpha2) ResourceClaimTemplates(namespace string) v1alpha2.ResourceClaimTemplateInterface { return &FakeResourceClaimTemplates{c, namespace} } -func (c *FakeResourceV1alpha1) ResourceClasses() v1alpha1.ResourceClassInterface { +func (c *FakeResourceV1alpha2) ResourceClasses() v1alpha2.ResourceClassInterface { return &FakeResourceClasses{c} } // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. -func (c *FakeResourceV1alpha1) RESTClient() rest.Interface { +func (c *FakeResourceV1alpha2) RESTClient() rest.Interface { var ret *rest.RESTClient return ret } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/fake_resourceclaim.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclaim.go similarity index 71% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/fake_resourceclaim.go rename to vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclaim.go index a458459f84..087e51f714 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/fake_resourceclaim.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclaim.go @@ -23,41 +23,40 @@ import ( json "encoding/json" "fmt" - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - resourcev1alpha1 "k8s.io/client-go/applyconfigurations/resource/v1alpha1" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" testing "k8s.io/client-go/testing" ) // FakeResourceClaims implements ResourceClaimInterface type FakeResourceClaims struct { - Fake *FakeResourceV1alpha1 + Fake *FakeResourceV1alpha2 ns string } -var resourceclaimsResource = schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1alpha1", Resource: "resourceclaims"} +var resourceclaimsResource = v1alpha2.SchemeGroupVersion.WithResource("resourceclaims") -var resourceclaimsKind = schema.GroupVersionKind{Group: "resource.k8s.io", Version: "v1alpha1", Kind: "ResourceClaim"} +var resourceclaimsKind = v1alpha2.SchemeGroupVersion.WithKind("ResourceClaim") // Get takes name of the resourceClaim, and returns the corresponding resourceClaim object, and an error if there is any. -func (c *FakeResourceClaims) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ResourceClaim, err error) { +func (c *FakeResourceClaims) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClaim, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(resourceclaimsResource, c.ns, name), &v1alpha1.ResourceClaim{}) + Invokes(testing.NewGetAction(resourceclaimsResource, c.ns, name), &v1alpha2.ResourceClaim{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClaim), err + return obj.(*v1alpha2.ResourceClaim), err } // List takes label and field selectors, and returns the list of ResourceClaims that match those selectors. -func (c *FakeResourceClaims) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ResourceClaimList, err error) { +func (c *FakeResourceClaims) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClaimList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(resourceclaimsResource, resourceclaimsKind, c.ns, opts), &v1alpha1.ResourceClaimList{}) + Invokes(testing.NewListAction(resourceclaimsResource, resourceclaimsKind, c.ns, opts), &v1alpha2.ResourceClaimList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeResourceClaims) List(ctx context.Context, opts v1.ListOptions) (res if label == nil { label = labels.Everything() } - list := &v1alpha1.ResourceClaimList{ListMeta: obj.(*v1alpha1.ResourceClaimList).ListMeta} - for _, item := range obj.(*v1alpha1.ResourceClaimList).Items { + list := &v1alpha2.ResourceClaimList{ListMeta: obj.(*v1alpha2.ResourceClaimList).ListMeta} + for _, item := range obj.(*v1alpha2.ResourceClaimList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -84,43 +83,43 @@ func (c *FakeResourceClaims) Watch(ctx context.Context, opts v1.ListOptions) (wa } // Create takes the representation of a resourceClaim and creates it. Returns the server's representation of the resourceClaim, and an error, if there is any. -func (c *FakeResourceClaims) Create(ctx context.Context, resourceClaim *v1alpha1.ResourceClaim, opts v1.CreateOptions) (result *v1alpha1.ResourceClaim, err error) { +func (c *FakeResourceClaims) Create(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.CreateOptions) (result *v1alpha2.ResourceClaim, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(resourceclaimsResource, c.ns, resourceClaim), &v1alpha1.ResourceClaim{}) + Invokes(testing.NewCreateAction(resourceclaimsResource, c.ns, resourceClaim), &v1alpha2.ResourceClaim{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClaim), err + return obj.(*v1alpha2.ResourceClaim), err } // Update takes the representation of a resourceClaim and updates it. Returns the server's representation of the resourceClaim, and an error, if there is any. -func (c *FakeResourceClaims) Update(ctx context.Context, resourceClaim *v1alpha1.ResourceClaim, opts v1.UpdateOptions) (result *v1alpha1.ResourceClaim, err error) { +func (c *FakeResourceClaims) Update(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.UpdateOptions) (result *v1alpha2.ResourceClaim, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(resourceclaimsResource, c.ns, resourceClaim), &v1alpha1.ResourceClaim{}) + Invokes(testing.NewUpdateAction(resourceclaimsResource, c.ns, resourceClaim), &v1alpha2.ResourceClaim{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClaim), err + return obj.(*v1alpha2.ResourceClaim), 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 *FakeResourceClaims) UpdateStatus(ctx context.Context, resourceClaim *v1alpha1.ResourceClaim, opts v1.UpdateOptions) (*v1alpha1.ResourceClaim, error) { +func (c *FakeResourceClaims) UpdateStatus(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.UpdateOptions) (*v1alpha2.ResourceClaim, error) { obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(resourceclaimsResource, "status", c.ns, resourceClaim), &v1alpha1.ResourceClaim{}) + Invokes(testing.NewUpdateSubresourceAction(resourceclaimsResource, "status", c.ns, resourceClaim), &v1alpha2.ResourceClaim{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClaim), err + return obj.(*v1alpha2.ResourceClaim), err } // Delete takes name of the resourceClaim and deletes it. Returns an error if one occurs. func (c *FakeResourceClaims) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(resourceclaimsResource, c.ns, name, opts), &v1alpha1.ResourceClaim{}) + Invokes(testing.NewDeleteActionWithOptions(resourceclaimsResource, c.ns, name, opts), &v1alpha2.ResourceClaim{}) return err } @@ -129,23 +128,23 @@ func (c *FakeResourceClaims) Delete(ctx context.Context, name string, opts v1.De func (c *FakeResourceClaims) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { action := testing.NewDeleteCollectionAction(resourceclaimsResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &v1alpha1.ResourceClaimList{}) + _, err := c.Fake.Invokes(action, &v1alpha2.ResourceClaimList{}) return err } // Patch applies the patch and returns the patched resourceClaim. -func (c *FakeResourceClaims) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceClaim, err error) { +func (c *FakeResourceClaims) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaim, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(resourceclaimsResource, c.ns, name, pt, data, subresources...), &v1alpha1.ResourceClaim{}) + Invokes(testing.NewPatchSubresourceAction(resourceclaimsResource, c.ns, name, pt, data, subresources...), &v1alpha2.ResourceClaim{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClaim), err + return obj.(*v1alpha2.ResourceClaim), err } // Apply takes the given apply declarative configuration, applies it and returns the applied resourceClaim. -func (c *FakeResourceClaims) Apply(ctx context.Context, resourceClaim *resourcev1alpha1.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClaim, err error) { +func (c *FakeResourceClaims) Apply(ctx context.Context, resourceClaim *resourcev1alpha2.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaim, err error) { if resourceClaim == nil { return nil, fmt.Errorf("resourceClaim provided to Apply must not be nil") } @@ -158,17 +157,17 @@ func (c *FakeResourceClaims) Apply(ctx context.Context, resourceClaim *resourcev return nil, fmt.Errorf("resourceClaim.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(resourceclaimsResource, c.ns, *name, types.ApplyPatchType, data), &v1alpha1.ResourceClaim{}) + Invokes(testing.NewPatchSubresourceAction(resourceclaimsResource, c.ns, *name, types.ApplyPatchType, data), &v1alpha2.ResourceClaim{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClaim), err + return obj.(*v1alpha2.ResourceClaim), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeResourceClaims) ApplyStatus(ctx context.Context, resourceClaim *resourcev1alpha1.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClaim, err error) { +func (c *FakeResourceClaims) ApplyStatus(ctx context.Context, resourceClaim *resourcev1alpha2.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaim, err error) { if resourceClaim == nil { return nil, fmt.Errorf("resourceClaim provided to Apply must not be nil") } @@ -181,10 +180,10 @@ func (c *FakeResourceClaims) ApplyStatus(ctx context.Context, resourceClaim *res return nil, fmt.Errorf("resourceClaim.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(resourceclaimsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1alpha1.ResourceClaim{}) + Invokes(testing.NewPatchSubresourceAction(resourceclaimsResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1alpha2.ResourceClaim{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClaim), err + return obj.(*v1alpha2.ResourceClaim), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/fake_resourceclaimtemplate.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclaimtemplate.go similarity index 70% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/fake_resourceclaimtemplate.go rename to vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclaimtemplate.go index be22ab6d37..2a1b4554eb 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/fake_resourceclaimtemplate.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclaimtemplate.go @@ -23,41 +23,40 @@ import ( json "encoding/json" "fmt" - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - resourcev1alpha1 "k8s.io/client-go/applyconfigurations/resource/v1alpha1" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" testing "k8s.io/client-go/testing" ) // FakeResourceClaimTemplates implements ResourceClaimTemplateInterface type FakeResourceClaimTemplates struct { - Fake *FakeResourceV1alpha1 + Fake *FakeResourceV1alpha2 ns string } -var resourceclaimtemplatesResource = schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1alpha1", Resource: "resourceclaimtemplates"} +var resourceclaimtemplatesResource = v1alpha2.SchemeGroupVersion.WithResource("resourceclaimtemplates") -var resourceclaimtemplatesKind = schema.GroupVersionKind{Group: "resource.k8s.io", Version: "v1alpha1", Kind: "ResourceClaimTemplate"} +var resourceclaimtemplatesKind = v1alpha2.SchemeGroupVersion.WithKind("ResourceClaimTemplate") // Get takes name of the resourceClaimTemplate, and returns the corresponding resourceClaimTemplate object, and an error if there is any. -func (c *FakeResourceClaimTemplates) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ResourceClaimTemplate, err error) { +func (c *FakeResourceClaimTemplates) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(resourceclaimtemplatesResource, c.ns, name), &v1alpha1.ResourceClaimTemplate{}) + Invokes(testing.NewGetAction(resourceclaimtemplatesResource, c.ns, name), &v1alpha2.ResourceClaimTemplate{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClaimTemplate), err + return obj.(*v1alpha2.ResourceClaimTemplate), err } // List takes label and field selectors, and returns the list of ResourceClaimTemplates that match those selectors. -func (c *FakeResourceClaimTemplates) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ResourceClaimTemplateList, err error) { +func (c *FakeResourceClaimTemplates) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClaimTemplateList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(resourceclaimtemplatesResource, resourceclaimtemplatesKind, c.ns, opts), &v1alpha1.ResourceClaimTemplateList{}) + Invokes(testing.NewListAction(resourceclaimtemplatesResource, resourceclaimtemplatesKind, c.ns, opts), &v1alpha2.ResourceClaimTemplateList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeResourceClaimTemplates) List(ctx context.Context, opts v1.ListOptio if label == nil { label = labels.Everything() } - list := &v1alpha1.ResourceClaimTemplateList{ListMeta: obj.(*v1alpha1.ResourceClaimTemplateList).ListMeta} - for _, item := range obj.(*v1alpha1.ResourceClaimTemplateList).Items { + list := &v1alpha2.ResourceClaimTemplateList{ListMeta: obj.(*v1alpha2.ResourceClaimTemplateList).ListMeta} + for _, item := range obj.(*v1alpha2.ResourceClaimTemplateList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -84,31 +83,31 @@ func (c *FakeResourceClaimTemplates) Watch(ctx context.Context, opts v1.ListOpti } // Create takes the representation of a resourceClaimTemplate and creates it. Returns the server's representation of the resourceClaimTemplate, and an error, if there is any. -func (c *FakeResourceClaimTemplates) Create(ctx context.Context, resourceClaimTemplate *v1alpha1.ResourceClaimTemplate, opts v1.CreateOptions) (result *v1alpha1.ResourceClaimTemplate, err error) { +func (c *FakeResourceClaimTemplates) Create(ctx context.Context, resourceClaimTemplate *v1alpha2.ResourceClaimTemplate, opts v1.CreateOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(resourceclaimtemplatesResource, c.ns, resourceClaimTemplate), &v1alpha1.ResourceClaimTemplate{}) + Invokes(testing.NewCreateAction(resourceclaimtemplatesResource, c.ns, resourceClaimTemplate), &v1alpha2.ResourceClaimTemplate{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClaimTemplate), err + return obj.(*v1alpha2.ResourceClaimTemplate), err } // Update takes the representation of a resourceClaimTemplate and updates it. Returns the server's representation of the resourceClaimTemplate, and an error, if there is any. -func (c *FakeResourceClaimTemplates) Update(ctx context.Context, resourceClaimTemplate *v1alpha1.ResourceClaimTemplate, opts v1.UpdateOptions) (result *v1alpha1.ResourceClaimTemplate, err error) { +func (c *FakeResourceClaimTemplates) Update(ctx context.Context, resourceClaimTemplate *v1alpha2.ResourceClaimTemplate, opts v1.UpdateOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(resourceclaimtemplatesResource, c.ns, resourceClaimTemplate), &v1alpha1.ResourceClaimTemplate{}) + Invokes(testing.NewUpdateAction(resourceclaimtemplatesResource, c.ns, resourceClaimTemplate), &v1alpha2.ResourceClaimTemplate{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClaimTemplate), err + return obj.(*v1alpha2.ResourceClaimTemplate), err } // Delete takes name of the resourceClaimTemplate and deletes it. Returns an error if one occurs. func (c *FakeResourceClaimTemplates) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(resourceclaimtemplatesResource, c.ns, name, opts), &v1alpha1.ResourceClaimTemplate{}) + Invokes(testing.NewDeleteActionWithOptions(resourceclaimtemplatesResource, c.ns, name, opts), &v1alpha2.ResourceClaimTemplate{}) return err } @@ -117,23 +116,23 @@ func (c *FakeResourceClaimTemplates) Delete(ctx context.Context, name string, op func (c *FakeResourceClaimTemplates) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { action := testing.NewDeleteCollectionAction(resourceclaimtemplatesResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &v1alpha1.ResourceClaimTemplateList{}) + _, err := c.Fake.Invokes(action, &v1alpha2.ResourceClaimTemplateList{}) return err } // Patch applies the patch and returns the patched resourceClaimTemplate. -func (c *FakeResourceClaimTemplates) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceClaimTemplate, err error) { +func (c *FakeResourceClaimTemplates) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaimTemplate, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(resourceclaimtemplatesResource, c.ns, name, pt, data, subresources...), &v1alpha1.ResourceClaimTemplate{}) + Invokes(testing.NewPatchSubresourceAction(resourceclaimtemplatesResource, c.ns, name, pt, data, subresources...), &v1alpha2.ResourceClaimTemplate{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClaimTemplate), err + return obj.(*v1alpha2.ResourceClaimTemplate), err } // Apply takes the given apply declarative configuration, applies it and returns the applied resourceClaimTemplate. -func (c *FakeResourceClaimTemplates) Apply(ctx context.Context, resourceClaimTemplate *resourcev1alpha1.ResourceClaimTemplateApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClaimTemplate, err error) { +func (c *FakeResourceClaimTemplates) Apply(ctx context.Context, resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplateApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { if resourceClaimTemplate == nil { return nil, fmt.Errorf("resourceClaimTemplate provided to Apply must not be nil") } @@ -146,10 +145,10 @@ func (c *FakeResourceClaimTemplates) Apply(ctx context.Context, resourceClaimTem return nil, fmt.Errorf("resourceClaimTemplate.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(resourceclaimtemplatesResource, c.ns, *name, types.ApplyPatchType, data), &v1alpha1.ResourceClaimTemplate{}) + Invokes(testing.NewPatchSubresourceAction(resourceclaimtemplatesResource, c.ns, *name, types.ApplyPatchType, data), &v1alpha2.ResourceClaimTemplate{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClaimTemplate), err + return obj.(*v1alpha2.ResourceClaimTemplate), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/fake_resourceclass.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclass.go similarity index 71% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/fake_resourceclass.go rename to vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclass.go index 80fb7ec034..4d247c5136 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/fake/fake_resourceclass.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/fake/fake_resourceclass.go @@ -23,39 +23,38 @@ import ( json "encoding/json" "fmt" - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - resourcev1alpha1 "k8s.io/client-go/applyconfigurations/resource/v1alpha1" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" testing "k8s.io/client-go/testing" ) // FakeResourceClasses implements ResourceClassInterface type FakeResourceClasses struct { - Fake *FakeResourceV1alpha1 + Fake *FakeResourceV1alpha2 } -var resourceclassesResource = schema.GroupVersionResource{Group: "resource.k8s.io", Version: "v1alpha1", Resource: "resourceclasses"} +var resourceclassesResource = v1alpha2.SchemeGroupVersion.WithResource("resourceclasses") -var resourceclassesKind = schema.GroupVersionKind{Group: "resource.k8s.io", Version: "v1alpha1", Kind: "ResourceClass"} +var resourceclassesKind = v1alpha2.SchemeGroupVersion.WithKind("ResourceClass") // Get takes name of the resourceClass, and returns the corresponding resourceClass object, and an error if there is any. -func (c *FakeResourceClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ResourceClass, err error) { +func (c *FakeResourceClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(resourceclassesResource, name), &v1alpha1.ResourceClass{}) + Invokes(testing.NewRootGetAction(resourceclassesResource, name), &v1alpha2.ResourceClass{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClass), err + return obj.(*v1alpha2.ResourceClass), err } // List takes label and field selectors, and returns the list of ResourceClasses that match those selectors. -func (c *FakeResourceClasses) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ResourceClassList, err error) { +func (c *FakeResourceClasses) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClassList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(resourceclassesResource, resourceclassesKind, opts), &v1alpha1.ResourceClassList{}) + Invokes(testing.NewRootListAction(resourceclassesResource, resourceclassesKind, opts), &v1alpha2.ResourceClassList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakeResourceClasses) List(ctx context.Context, opts v1.ListOptions) (re if label == nil { label = labels.Everything() } - list := &v1alpha1.ResourceClassList{ListMeta: obj.(*v1alpha1.ResourceClassList).ListMeta} - for _, item := range obj.(*v1alpha1.ResourceClassList).Items { + list := &v1alpha2.ResourceClassList{ListMeta: obj.(*v1alpha2.ResourceClassList).ListMeta} + for _, item := range obj.(*v1alpha2.ResourceClassList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -80,29 +79,29 @@ func (c *FakeResourceClasses) Watch(ctx context.Context, opts v1.ListOptions) (w } // Create takes the representation of a resourceClass and creates it. Returns the server's representation of the resourceClass, and an error, if there is any. -func (c *FakeResourceClasses) Create(ctx context.Context, resourceClass *v1alpha1.ResourceClass, opts v1.CreateOptions) (result *v1alpha1.ResourceClass, err error) { +func (c *FakeResourceClasses) Create(ctx context.Context, resourceClass *v1alpha2.ResourceClass, opts v1.CreateOptions) (result *v1alpha2.ResourceClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(resourceclassesResource, resourceClass), &v1alpha1.ResourceClass{}) + Invokes(testing.NewRootCreateAction(resourceclassesResource, resourceClass), &v1alpha2.ResourceClass{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClass), err + return obj.(*v1alpha2.ResourceClass), err } // Update takes the representation of a resourceClass and updates it. Returns the server's representation of the resourceClass, and an error, if there is any. -func (c *FakeResourceClasses) Update(ctx context.Context, resourceClass *v1alpha1.ResourceClass, opts v1.UpdateOptions) (result *v1alpha1.ResourceClass, err error) { +func (c *FakeResourceClasses) Update(ctx context.Context, resourceClass *v1alpha2.ResourceClass, opts v1.UpdateOptions) (result *v1alpha2.ResourceClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(resourceclassesResource, resourceClass), &v1alpha1.ResourceClass{}) + Invokes(testing.NewRootUpdateAction(resourceclassesResource, resourceClass), &v1alpha2.ResourceClass{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClass), err + return obj.(*v1alpha2.ResourceClass), err } // Delete takes name of the resourceClass and deletes it. Returns an error if one occurs. func (c *FakeResourceClasses) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(resourceclassesResource, name, opts), &v1alpha1.ResourceClass{}) + Invokes(testing.NewRootDeleteActionWithOptions(resourceclassesResource, name, opts), &v1alpha2.ResourceClass{}) return err } @@ -110,22 +109,22 @@ func (c *FakeResourceClasses) Delete(ctx context.Context, name string, opts v1.D func (c *FakeResourceClasses) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(resourceclassesResource, listOpts) - _, err := c.Fake.Invokes(action, &v1alpha1.ResourceClassList{}) + _, err := c.Fake.Invokes(action, &v1alpha2.ResourceClassList{}) return err } // Patch applies the patch and returns the patched resourceClass. -func (c *FakeResourceClasses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceClass, err error) { +func (c *FakeResourceClasses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(resourceclassesResource, name, pt, data, subresources...), &v1alpha1.ResourceClass{}) + Invokes(testing.NewRootPatchSubresourceAction(resourceclassesResource, name, pt, data, subresources...), &v1alpha2.ResourceClass{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClass), err + return obj.(*v1alpha2.ResourceClass), err } // Apply takes the given apply declarative configuration, applies it and returns the applied resourceClass. -func (c *FakeResourceClasses) Apply(ctx context.Context, resourceClass *resourcev1alpha1.ResourceClassApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClass, err error) { +func (c *FakeResourceClasses) Apply(ctx context.Context, resourceClass *resourcev1alpha2.ResourceClassApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClass, err error) { if resourceClass == nil { return nil, fmt.Errorf("resourceClass provided to Apply must not be nil") } @@ -138,9 +137,9 @@ func (c *FakeResourceClasses) Apply(ctx context.Context, resourceClass *resource return nil, fmt.Errorf("resourceClass.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(resourceclassesResource, *name, types.ApplyPatchType, data), &v1alpha1.ResourceClass{}) + Invokes(testing.NewRootPatchSubresourceAction(resourceclassesResource, *name, types.ApplyPatchType, data), &v1alpha2.ResourceClass{}) if obj == nil { return nil, err } - return obj.(*v1alpha1.ResourceClass), err + return obj.(*v1alpha2.ResourceClass), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go similarity index 92% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/generated_expansion.go rename to vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go index df88c2f93b..2c02e9ce74 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/generated_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go @@ -16,9 +16,9 @@ limitations under the License. // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 -type PodSchedulingExpansion interface{} +type PodSchedulingContextExpansion interface{} type ResourceClaimExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/podschedulingcontext.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/podschedulingcontext.go new file mode 100644 index 0000000000..72e81a29e3 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/podschedulingcontext.go @@ -0,0 +1,256 @@ +/* +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 v1alpha2 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// PodSchedulingContextsGetter has a method to return a PodSchedulingContextInterface. +// A group's client should implement this interface. +type PodSchedulingContextsGetter interface { + PodSchedulingContexts(namespace string) PodSchedulingContextInterface +} + +// PodSchedulingContextInterface has methods to work with PodSchedulingContext resources. +type PodSchedulingContextInterface interface { + Create(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.CreateOptions) (*v1alpha2.PodSchedulingContext, error) + Update(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.UpdateOptions) (*v1alpha2.PodSchedulingContext, error) + UpdateStatus(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.UpdateOptions) (*v1alpha2.PodSchedulingContext, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.PodSchedulingContext, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.PodSchedulingContextList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.PodSchedulingContext, err error) + Apply(ctx context.Context, podSchedulingContext *resourcev1alpha2.PodSchedulingContextApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.PodSchedulingContext, err error) + ApplyStatus(ctx context.Context, podSchedulingContext *resourcev1alpha2.PodSchedulingContextApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.PodSchedulingContext, err error) + PodSchedulingContextExpansion +} + +// podSchedulingContexts implements PodSchedulingContextInterface +type podSchedulingContexts struct { + client rest.Interface + ns string +} + +// newPodSchedulingContexts returns a PodSchedulingContexts +func newPodSchedulingContexts(c *ResourceV1alpha2Client, namespace string) *podSchedulingContexts { + return &podSchedulingContexts{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the podSchedulingContext, and returns the corresponding podSchedulingContext object, and an error if there is any. +func (c *podSchedulingContexts) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.PodSchedulingContext, err error) { + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Get(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of PodSchedulingContexts that match those selectors. +func (c *podSchedulingContexts) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.PodSchedulingContextList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha2.PodSchedulingContextList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested podSchedulingContexts. +func (c *podSchedulingContexts) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a podSchedulingContext and creates it. Returns the server's representation of the podSchedulingContext, and an error, if there is any. +func (c *podSchedulingContexts) Create(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.CreateOptions) (result *v1alpha2.PodSchedulingContext, err error) { + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Post(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(podSchedulingContext). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a podSchedulingContext and updates it. Returns the server's representation of the podSchedulingContext, and an error, if there is any. +func (c *podSchedulingContexts) Update(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.UpdateOptions) (result *v1alpha2.PodSchedulingContext, err error) { + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Put(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(podSchedulingContext.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(podSchedulingContext). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *podSchedulingContexts) UpdateStatus(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.UpdateOptions) (result *v1alpha2.PodSchedulingContext, err error) { + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Put(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(podSchedulingContext.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(podSchedulingContext). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the podSchedulingContext and deletes it. Returns an error if one occurs. +func (c *podSchedulingContexts) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *podSchedulingContexts) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched podSchedulingContext. +func (c *podSchedulingContexts) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.PodSchedulingContext, err error) { + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied podSchedulingContext. +func (c *podSchedulingContexts) Apply(ctx context.Context, podSchedulingContext *resourcev1alpha2.PodSchedulingContextApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.PodSchedulingContext, err error) { + if podSchedulingContext == nil { + return nil, fmt.Errorf("podSchedulingContext provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(podSchedulingContext) + if err != nil { + return nil, err + } + name := podSchedulingContext.Name + if name == nil { + return nil, fmt.Errorf("podSchedulingContext.Name must be provided to Apply") + } + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Patch(types.ApplyPatchType). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// ApplyStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). +func (c *podSchedulingContexts) ApplyStatus(ctx context.Context, podSchedulingContext *resourcev1alpha2.PodSchedulingContextApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.PodSchedulingContext, err error) { + if podSchedulingContext == nil { + return nil, fmt.Errorf("podSchedulingContext provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(podSchedulingContext) + if err != nil { + return nil, err + } + + name := podSchedulingContext.Name + if name == nil { + return nil, fmt.Errorf("podSchedulingContext.Name must be provided to Apply") + } + + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Patch(types.ApplyPatchType). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(*name). + SubResource("status"). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resource_client.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go similarity index 66% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resource_client.go rename to vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go index 2355bf7ccb..d5795fd628 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resource_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go @@ -16,49 +16,49 @@ limitations under the License. // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( "net/http" - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" "k8s.io/client-go/kubernetes/scheme" rest "k8s.io/client-go/rest" ) -type ResourceV1alpha1Interface interface { +type ResourceV1alpha2Interface interface { RESTClient() rest.Interface - PodSchedulingsGetter + PodSchedulingContextsGetter ResourceClaimsGetter ResourceClaimTemplatesGetter ResourceClassesGetter } -// ResourceV1alpha1Client is used to interact with features provided by the resource.k8s.io group. -type ResourceV1alpha1Client struct { +// ResourceV1alpha2Client is used to interact with features provided by the resource.k8s.io group. +type ResourceV1alpha2Client struct { restClient rest.Interface } -func (c *ResourceV1alpha1Client) PodSchedulings(namespace string) PodSchedulingInterface { - return newPodSchedulings(c, namespace) +func (c *ResourceV1alpha2Client) PodSchedulingContexts(namespace string) PodSchedulingContextInterface { + return newPodSchedulingContexts(c, namespace) } -func (c *ResourceV1alpha1Client) ResourceClaims(namespace string) ResourceClaimInterface { +func (c *ResourceV1alpha2Client) ResourceClaims(namespace string) ResourceClaimInterface { return newResourceClaims(c, namespace) } -func (c *ResourceV1alpha1Client) ResourceClaimTemplates(namespace string) ResourceClaimTemplateInterface { +func (c *ResourceV1alpha2Client) ResourceClaimTemplates(namespace string) ResourceClaimTemplateInterface { return newResourceClaimTemplates(c, namespace) } -func (c *ResourceV1alpha1Client) ResourceClasses() ResourceClassInterface { +func (c *ResourceV1alpha2Client) ResourceClasses() ResourceClassInterface { return newResourceClasses(c) } -// NewForConfig creates a new ResourceV1alpha1Client for the given config. +// NewForConfig creates a new ResourceV1alpha2Client for the given config. // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), // where httpClient was generated with rest.HTTPClientFor(c). -func NewForConfig(c *rest.Config) (*ResourceV1alpha1Client, error) { +func NewForConfig(c *rest.Config) (*ResourceV1alpha2Client, error) { config := *c if err := setConfigDefaults(&config); err != nil { return nil, err @@ -70,9 +70,9 @@ func NewForConfig(c *rest.Config) (*ResourceV1alpha1Client, error) { return NewForConfigAndClient(&config, httpClient) } -// NewForConfigAndClient creates a new ResourceV1alpha1Client for the given config and http client. +// NewForConfigAndClient creates a new ResourceV1alpha2Client for the given config and http client. // Note the http client provided takes precedence over the configured transport values. -func NewForConfigAndClient(c *rest.Config, h *http.Client) (*ResourceV1alpha1Client, error) { +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*ResourceV1alpha2Client, error) { config := *c if err := setConfigDefaults(&config); err != nil { return nil, err @@ -81,12 +81,12 @@ func NewForConfigAndClient(c *rest.Config, h *http.Client) (*ResourceV1alpha1Cli if err != nil { return nil, err } - return &ResourceV1alpha1Client{client}, nil + return &ResourceV1alpha2Client{client}, nil } -// NewForConfigOrDie creates a new ResourceV1alpha1Client for the given config and +// NewForConfigOrDie creates a new ResourceV1alpha2Client for the given config and // panics if there is an error in the config. -func NewForConfigOrDie(c *rest.Config) *ResourceV1alpha1Client { +func NewForConfigOrDie(c *rest.Config) *ResourceV1alpha2Client { client, err := NewForConfig(c) if err != nil { panic(err) @@ -94,13 +94,13 @@ func NewForConfigOrDie(c *rest.Config) *ResourceV1alpha1Client { return client } -// New creates a new ResourceV1alpha1Client for the given RESTClient. -func New(c rest.Interface) *ResourceV1alpha1Client { - return &ResourceV1alpha1Client{c} +// New creates a new ResourceV1alpha2Client for the given RESTClient. +func New(c rest.Interface) *ResourceV1alpha2Client { + return &ResourceV1alpha2Client{c} } func setConfigDefaults(config *rest.Config) error { - gv := v1alpha1.SchemeGroupVersion + gv := v1alpha2.SchemeGroupVersion config.GroupVersion = &gv config.APIPath = "/apis" config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() @@ -114,7 +114,7 @@ func setConfigDefaults(config *rest.Config) error { // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. -func (c *ResourceV1alpha1Client) RESTClient() rest.Interface { +func (c *ResourceV1alpha2Client) RESTClient() rest.Interface { if c == nil { return nil } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclaim.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaim.go similarity index 79% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclaim.go rename to vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaim.go index cd2d0c7821..cfb27c9db6 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclaim.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaim.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( "context" @@ -24,11 +24,11 @@ import ( "fmt" "time" - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - resourcev1alpha1 "k8s.io/client-go/applyconfigurations/resource/v1alpha1" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" scheme "k8s.io/client-go/kubernetes/scheme" rest "k8s.io/client-go/rest" ) @@ -41,17 +41,17 @@ type ResourceClaimsGetter interface { // ResourceClaimInterface has methods to work with ResourceClaim resources. type ResourceClaimInterface interface { - Create(ctx context.Context, resourceClaim *v1alpha1.ResourceClaim, opts v1.CreateOptions) (*v1alpha1.ResourceClaim, error) - Update(ctx context.Context, resourceClaim *v1alpha1.ResourceClaim, opts v1.UpdateOptions) (*v1alpha1.ResourceClaim, error) - UpdateStatus(ctx context.Context, resourceClaim *v1alpha1.ResourceClaim, opts v1.UpdateOptions) (*v1alpha1.ResourceClaim, error) + Create(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.CreateOptions) (*v1alpha2.ResourceClaim, error) + Update(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.UpdateOptions) (*v1alpha2.ResourceClaim, error) + UpdateStatus(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.UpdateOptions) (*v1alpha2.ResourceClaim, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ResourceClaim, error) - List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ResourceClaimList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.ResourceClaim, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.ResourceClaimList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceClaim, err error) - Apply(ctx context.Context, resourceClaim *resourcev1alpha1.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClaim, err error) - ApplyStatus(ctx context.Context, resourceClaim *resourcev1alpha1.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClaim, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaim, err error) + Apply(ctx context.Context, resourceClaim *resourcev1alpha2.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaim, err error) + ApplyStatus(ctx context.Context, resourceClaim *resourcev1alpha2.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaim, err error) ResourceClaimExpansion } @@ -62,7 +62,7 @@ type resourceClaims struct { } // newResourceClaims returns a ResourceClaims -func newResourceClaims(c *ResourceV1alpha1Client, namespace string) *resourceClaims { +func newResourceClaims(c *ResourceV1alpha2Client, namespace string) *resourceClaims { return &resourceClaims{ client: c.RESTClient(), ns: namespace, @@ -70,8 +70,8 @@ func newResourceClaims(c *ResourceV1alpha1Client, namespace string) *resourceCla } // Get takes name of the resourceClaim, and returns the corresponding resourceClaim object, and an error if there is any. -func (c *resourceClaims) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ResourceClaim, err error) { - result = &v1alpha1.ResourceClaim{} +func (c *resourceClaims) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClaim, err error) { + result = &v1alpha2.ResourceClaim{} err = c.client.Get(). Namespace(c.ns). Resource("resourceclaims"). @@ -83,12 +83,12 @@ func (c *resourceClaims) Get(ctx context.Context, name string, options v1.GetOpt } // List takes label and field selectors, and returns the list of ResourceClaims that match those selectors. -func (c *resourceClaims) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ResourceClaimList, err error) { +func (c *resourceClaims) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClaimList, err error) { var timeout time.Duration if opts.TimeoutSeconds != nil { timeout = time.Duration(*opts.TimeoutSeconds) * time.Second } - result = &v1alpha1.ResourceClaimList{} + result = &v1alpha2.ResourceClaimList{} err = c.client.Get(). Namespace(c.ns). Resource("resourceclaims"). @@ -115,8 +115,8 @@ func (c *resourceClaims) Watch(ctx context.Context, opts v1.ListOptions) (watch. } // Create takes the representation of a resourceClaim and creates it. Returns the server's representation of the resourceClaim, and an error, if there is any. -func (c *resourceClaims) Create(ctx context.Context, resourceClaim *v1alpha1.ResourceClaim, opts v1.CreateOptions) (result *v1alpha1.ResourceClaim, err error) { - result = &v1alpha1.ResourceClaim{} +func (c *resourceClaims) Create(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.CreateOptions) (result *v1alpha2.ResourceClaim, err error) { + result = &v1alpha2.ResourceClaim{} err = c.client.Post(). Namespace(c.ns). Resource("resourceclaims"). @@ -128,8 +128,8 @@ func (c *resourceClaims) Create(ctx context.Context, resourceClaim *v1alpha1.Res } // Update takes the representation of a resourceClaim and updates it. Returns the server's representation of the resourceClaim, and an error, if there is any. -func (c *resourceClaims) Update(ctx context.Context, resourceClaim *v1alpha1.ResourceClaim, opts v1.UpdateOptions) (result *v1alpha1.ResourceClaim, err error) { - result = &v1alpha1.ResourceClaim{} +func (c *resourceClaims) Update(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.UpdateOptions) (result *v1alpha2.ResourceClaim, err error) { + result = &v1alpha2.ResourceClaim{} err = c.client.Put(). Namespace(c.ns). Resource("resourceclaims"). @@ -143,8 +143,8 @@ func (c *resourceClaims) Update(ctx context.Context, resourceClaim *v1alpha1.Res // UpdateStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *resourceClaims) UpdateStatus(ctx context.Context, resourceClaim *v1alpha1.ResourceClaim, opts v1.UpdateOptions) (result *v1alpha1.ResourceClaim, err error) { - result = &v1alpha1.ResourceClaim{} +func (c *resourceClaims) UpdateStatus(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.UpdateOptions) (result *v1alpha2.ResourceClaim, err error) { + result = &v1alpha2.ResourceClaim{} err = c.client.Put(). Namespace(c.ns). Resource("resourceclaims"). @@ -185,8 +185,8 @@ func (c *resourceClaims) DeleteCollection(ctx context.Context, opts v1.DeleteOpt } // Patch applies the patch and returns the patched resourceClaim. -func (c *resourceClaims) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceClaim, err error) { - result = &v1alpha1.ResourceClaim{} +func (c *resourceClaims) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaim, err error) { + result = &v1alpha2.ResourceClaim{} err = c.client.Patch(pt). Namespace(c.ns). Resource("resourceclaims"). @@ -200,7 +200,7 @@ func (c *resourceClaims) Patch(ctx context.Context, name string, pt types.PatchT } // Apply takes the given apply declarative configuration, applies it and returns the applied resourceClaim. -func (c *resourceClaims) Apply(ctx context.Context, resourceClaim *resourcev1alpha1.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClaim, err error) { +func (c *resourceClaims) Apply(ctx context.Context, resourceClaim *resourcev1alpha2.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaim, err error) { if resourceClaim == nil { return nil, fmt.Errorf("resourceClaim provided to Apply must not be nil") } @@ -213,7 +213,7 @@ func (c *resourceClaims) Apply(ctx context.Context, resourceClaim *resourcev1alp if name == nil { return nil, fmt.Errorf("resourceClaim.Name must be provided to Apply") } - result = &v1alpha1.ResourceClaim{} + result = &v1alpha2.ResourceClaim{} err = c.client.Patch(types.ApplyPatchType). Namespace(c.ns). Resource("resourceclaims"). @@ -227,7 +227,7 @@ func (c *resourceClaims) Apply(ctx context.Context, resourceClaim *resourcev1alp // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *resourceClaims) ApplyStatus(ctx context.Context, resourceClaim *resourcev1alpha1.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClaim, err error) { +func (c *resourceClaims) ApplyStatus(ctx context.Context, resourceClaim *resourcev1alpha2.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaim, err error) { if resourceClaim == nil { return nil, fmt.Errorf("resourceClaim provided to Apply must not be nil") } @@ -242,7 +242,7 @@ func (c *resourceClaims) ApplyStatus(ctx context.Context, resourceClaim *resourc return nil, fmt.Errorf("resourceClaim.Name must be provided to Apply") } - result = &v1alpha1.ResourceClaim{} + result = &v1alpha2.ResourceClaim{} err = c.client.Patch(types.ApplyPatchType). Namespace(c.ns). Resource("resourceclaims"). diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclaimtemplate.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaimtemplate.go similarity index 80% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclaimtemplate.go rename to vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaimtemplate.go index b6cc3d96ec..3f4e320064 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclaimtemplate.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaimtemplate.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( "context" @@ -24,11 +24,11 @@ import ( "fmt" "time" - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - resourcev1alpha1 "k8s.io/client-go/applyconfigurations/resource/v1alpha1" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" scheme "k8s.io/client-go/kubernetes/scheme" rest "k8s.io/client-go/rest" ) @@ -41,15 +41,15 @@ type ResourceClaimTemplatesGetter interface { // ResourceClaimTemplateInterface has methods to work with ResourceClaimTemplate resources. type ResourceClaimTemplateInterface interface { - Create(ctx context.Context, resourceClaimTemplate *v1alpha1.ResourceClaimTemplate, opts v1.CreateOptions) (*v1alpha1.ResourceClaimTemplate, error) - Update(ctx context.Context, resourceClaimTemplate *v1alpha1.ResourceClaimTemplate, opts v1.UpdateOptions) (*v1alpha1.ResourceClaimTemplate, error) + Create(ctx context.Context, resourceClaimTemplate *v1alpha2.ResourceClaimTemplate, opts v1.CreateOptions) (*v1alpha2.ResourceClaimTemplate, error) + Update(ctx context.Context, resourceClaimTemplate *v1alpha2.ResourceClaimTemplate, opts v1.UpdateOptions) (*v1alpha2.ResourceClaimTemplate, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ResourceClaimTemplate, error) - List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ResourceClaimTemplateList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.ResourceClaimTemplate, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.ResourceClaimTemplateList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceClaimTemplate, err error) - Apply(ctx context.Context, resourceClaimTemplate *resourcev1alpha1.ResourceClaimTemplateApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClaimTemplate, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaimTemplate, err error) + Apply(ctx context.Context, resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplateApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaimTemplate, err error) ResourceClaimTemplateExpansion } @@ -60,7 +60,7 @@ type resourceClaimTemplates struct { } // newResourceClaimTemplates returns a ResourceClaimTemplates -func newResourceClaimTemplates(c *ResourceV1alpha1Client, namespace string) *resourceClaimTemplates { +func newResourceClaimTemplates(c *ResourceV1alpha2Client, namespace string) *resourceClaimTemplates { return &resourceClaimTemplates{ client: c.RESTClient(), ns: namespace, @@ -68,8 +68,8 @@ func newResourceClaimTemplates(c *ResourceV1alpha1Client, namespace string) *res } // Get takes name of the resourceClaimTemplate, and returns the corresponding resourceClaimTemplate object, and an error if there is any. -func (c *resourceClaimTemplates) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ResourceClaimTemplate, err error) { - result = &v1alpha1.ResourceClaimTemplate{} +func (c *resourceClaimTemplates) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { + result = &v1alpha2.ResourceClaimTemplate{} err = c.client.Get(). Namespace(c.ns). Resource("resourceclaimtemplates"). @@ -81,12 +81,12 @@ func (c *resourceClaimTemplates) Get(ctx context.Context, name string, options v } // List takes label and field selectors, and returns the list of ResourceClaimTemplates that match those selectors. -func (c *resourceClaimTemplates) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ResourceClaimTemplateList, err error) { +func (c *resourceClaimTemplates) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClaimTemplateList, err error) { var timeout time.Duration if opts.TimeoutSeconds != nil { timeout = time.Duration(*opts.TimeoutSeconds) * time.Second } - result = &v1alpha1.ResourceClaimTemplateList{} + result = &v1alpha2.ResourceClaimTemplateList{} err = c.client.Get(). Namespace(c.ns). Resource("resourceclaimtemplates"). @@ -113,8 +113,8 @@ func (c *resourceClaimTemplates) Watch(ctx context.Context, opts v1.ListOptions) } // Create takes the representation of a resourceClaimTemplate and creates it. Returns the server's representation of the resourceClaimTemplate, and an error, if there is any. -func (c *resourceClaimTemplates) Create(ctx context.Context, resourceClaimTemplate *v1alpha1.ResourceClaimTemplate, opts v1.CreateOptions) (result *v1alpha1.ResourceClaimTemplate, err error) { - result = &v1alpha1.ResourceClaimTemplate{} +func (c *resourceClaimTemplates) Create(ctx context.Context, resourceClaimTemplate *v1alpha2.ResourceClaimTemplate, opts v1.CreateOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { + result = &v1alpha2.ResourceClaimTemplate{} err = c.client.Post(). Namespace(c.ns). Resource("resourceclaimtemplates"). @@ -126,8 +126,8 @@ func (c *resourceClaimTemplates) Create(ctx context.Context, resourceClaimTempla } // Update takes the representation of a resourceClaimTemplate and updates it. Returns the server's representation of the resourceClaimTemplate, and an error, if there is any. -func (c *resourceClaimTemplates) Update(ctx context.Context, resourceClaimTemplate *v1alpha1.ResourceClaimTemplate, opts v1.UpdateOptions) (result *v1alpha1.ResourceClaimTemplate, err error) { - result = &v1alpha1.ResourceClaimTemplate{} +func (c *resourceClaimTemplates) Update(ctx context.Context, resourceClaimTemplate *v1alpha2.ResourceClaimTemplate, opts v1.UpdateOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { + result = &v1alpha2.ResourceClaimTemplate{} err = c.client.Put(). Namespace(c.ns). Resource("resourceclaimtemplates"). @@ -167,8 +167,8 @@ func (c *resourceClaimTemplates) DeleteCollection(ctx context.Context, opts v1.D } // Patch applies the patch and returns the patched resourceClaimTemplate. -func (c *resourceClaimTemplates) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceClaimTemplate, err error) { - result = &v1alpha1.ResourceClaimTemplate{} +func (c *resourceClaimTemplates) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaimTemplate, err error) { + result = &v1alpha2.ResourceClaimTemplate{} err = c.client.Patch(pt). Namespace(c.ns). Resource("resourceclaimtemplates"). @@ -182,7 +182,7 @@ func (c *resourceClaimTemplates) Patch(ctx context.Context, name string, pt type } // Apply takes the given apply declarative configuration, applies it and returns the applied resourceClaimTemplate. -func (c *resourceClaimTemplates) Apply(ctx context.Context, resourceClaimTemplate *resourcev1alpha1.ResourceClaimTemplateApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClaimTemplate, err error) { +func (c *resourceClaimTemplates) Apply(ctx context.Context, resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplateApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { if resourceClaimTemplate == nil { return nil, fmt.Errorf("resourceClaimTemplate provided to Apply must not be nil") } @@ -195,7 +195,7 @@ func (c *resourceClaimTemplates) Apply(ctx context.Context, resourceClaimTemplat if name == nil { return nil, fmt.Errorf("resourceClaimTemplate.Name must be provided to Apply") } - result = &v1alpha1.ResourceClaimTemplate{} + result = &v1alpha2.ResourceClaimTemplate{} err = c.client.Patch(types.ApplyPatchType). Namespace(c.ns). Resource("resourceclaimtemplates"). diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclass.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclass.go similarity index 80% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclass.go rename to vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclass.go index 9c8b454639..95a4ac5668 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclass.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclass.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( "context" @@ -24,11 +24,11 @@ import ( "fmt" "time" - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - resourcev1alpha1 "k8s.io/client-go/applyconfigurations/resource/v1alpha1" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" scheme "k8s.io/client-go/kubernetes/scheme" rest "k8s.io/client-go/rest" ) @@ -41,15 +41,15 @@ type ResourceClassesGetter interface { // ResourceClassInterface has methods to work with ResourceClass resources. type ResourceClassInterface interface { - Create(ctx context.Context, resourceClass *v1alpha1.ResourceClass, opts v1.CreateOptions) (*v1alpha1.ResourceClass, error) - Update(ctx context.Context, resourceClass *v1alpha1.ResourceClass, opts v1.UpdateOptions) (*v1alpha1.ResourceClass, error) + Create(ctx context.Context, resourceClass *v1alpha2.ResourceClass, opts v1.CreateOptions) (*v1alpha2.ResourceClass, error) + Update(ctx context.Context, resourceClass *v1alpha2.ResourceClass, opts v1.UpdateOptions) (*v1alpha2.ResourceClass, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ResourceClass, error) - List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ResourceClassList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.ResourceClass, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.ResourceClassList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceClass, err error) - Apply(ctx context.Context, resourceClass *resourcev1alpha1.ResourceClassApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClass, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClass, err error) + Apply(ctx context.Context, resourceClass *resourcev1alpha2.ResourceClassApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClass, err error) ResourceClassExpansion } @@ -59,15 +59,15 @@ type resourceClasses struct { } // newResourceClasses returns a ResourceClasses -func newResourceClasses(c *ResourceV1alpha1Client) *resourceClasses { +func newResourceClasses(c *ResourceV1alpha2Client) *resourceClasses { return &resourceClasses{ client: c.RESTClient(), } } // Get takes name of the resourceClass, and returns the corresponding resourceClass object, and an error if there is any. -func (c *resourceClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ResourceClass, err error) { - result = &v1alpha1.ResourceClass{} +func (c *resourceClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClass, err error) { + result = &v1alpha2.ResourceClass{} err = c.client.Get(). Resource("resourceclasses"). Name(name). @@ -78,12 +78,12 @@ func (c *resourceClasses) Get(ctx context.Context, name string, options v1.GetOp } // List takes label and field selectors, and returns the list of ResourceClasses that match those selectors. -func (c *resourceClasses) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ResourceClassList, err error) { +func (c *resourceClasses) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClassList, err error) { var timeout time.Duration if opts.TimeoutSeconds != nil { timeout = time.Duration(*opts.TimeoutSeconds) * time.Second } - result = &v1alpha1.ResourceClassList{} + result = &v1alpha2.ResourceClassList{} err = c.client.Get(). Resource("resourceclasses"). VersionedParams(&opts, scheme.ParameterCodec). @@ -108,8 +108,8 @@ func (c *resourceClasses) Watch(ctx context.Context, opts v1.ListOptions) (watch } // Create takes the representation of a resourceClass and creates it. Returns the server's representation of the resourceClass, and an error, if there is any. -func (c *resourceClasses) Create(ctx context.Context, resourceClass *v1alpha1.ResourceClass, opts v1.CreateOptions) (result *v1alpha1.ResourceClass, err error) { - result = &v1alpha1.ResourceClass{} +func (c *resourceClasses) Create(ctx context.Context, resourceClass *v1alpha2.ResourceClass, opts v1.CreateOptions) (result *v1alpha2.ResourceClass, err error) { + result = &v1alpha2.ResourceClass{} err = c.client.Post(). Resource("resourceclasses"). VersionedParams(&opts, scheme.ParameterCodec). @@ -120,8 +120,8 @@ func (c *resourceClasses) Create(ctx context.Context, resourceClass *v1alpha1.Re } // Update takes the representation of a resourceClass and updates it. Returns the server's representation of the resourceClass, and an error, if there is any. -func (c *resourceClasses) Update(ctx context.Context, resourceClass *v1alpha1.ResourceClass, opts v1.UpdateOptions) (result *v1alpha1.ResourceClass, err error) { - result = &v1alpha1.ResourceClass{} +func (c *resourceClasses) Update(ctx context.Context, resourceClass *v1alpha2.ResourceClass, opts v1.UpdateOptions) (result *v1alpha2.ResourceClass, err error) { + result = &v1alpha2.ResourceClass{} err = c.client.Put(). Resource("resourceclasses"). Name(resourceClass.Name). @@ -158,8 +158,8 @@ func (c *resourceClasses) DeleteCollection(ctx context.Context, opts v1.DeleteOp } // Patch applies the patch and returns the patched resourceClass. -func (c *resourceClasses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceClass, err error) { - result = &v1alpha1.ResourceClass{} +func (c *resourceClasses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClass, err error) { + result = &v1alpha2.ResourceClass{} err = c.client.Patch(pt). Resource("resourceclasses"). Name(name). @@ -172,7 +172,7 @@ func (c *resourceClasses) Patch(ctx context.Context, name string, pt types.Patch } // Apply takes the given apply declarative configuration, applies it and returns the applied resourceClass. -func (c *resourceClasses) Apply(ctx context.Context, resourceClass *resourcev1alpha1.ResourceClassApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClass, err error) { +func (c *resourceClasses) Apply(ctx context.Context, resourceClass *resourcev1alpha2.ResourceClassApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClass, err error) { if resourceClass == nil { return nil, fmt.Errorf("resourceClass provided to Apply must not be nil") } @@ -185,7 +185,7 @@ func (c *resourceClasses) Apply(ctx context.Context, resourceClass *resourcev1al if name == nil { return nil, fmt.Errorf("resourceClass.Name must be provided to Apply") } - result = &v1alpha1.ResourceClass{} + result = &v1alpha2.ResourceClass{} err = c.client.Patch(types.ApplyPatchType). Resource("resourceclasses"). Name(*name). diff --git a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1/fake/fake_priorityclass.go b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1/fake/fake_priorityclass.go index 30f82270e7..40ab9fb407 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1/fake/fake_priorityclass.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1/fake/fake_priorityclass.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - schedulingv1 "k8s.io/api/scheduling/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/scheduling/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsschedulingv1 "k8s.io/client-go/applyconfigurations/scheduling/v1" + schedulingv1 "k8s.io/client-go/applyconfigurations/scheduling/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakePriorityClasses struct { Fake *FakeSchedulingV1 } -var priorityclassesResource = schema.GroupVersionResource{Group: "scheduling.k8s.io", Version: "v1", Resource: "priorityclasses"} +var priorityclassesResource = v1.SchemeGroupVersion.WithResource("priorityclasses") -var priorityclassesKind = schema.GroupVersionKind{Group: "scheduling.k8s.io", Version: "v1", Kind: "PriorityClass"} +var priorityclassesKind = v1.SchemeGroupVersion.WithKind("PriorityClass") // Get takes name of the priorityClass, and returns the corresponding priorityClass object, and an error if there is any. -func (c *FakePriorityClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *schedulingv1.PriorityClass, err error) { +func (c *FakePriorityClasses) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.PriorityClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(priorityclassesResource, name), &schedulingv1.PriorityClass{}) + Invokes(testing.NewRootGetAction(priorityclassesResource, name), &v1.PriorityClass{}) if obj == nil { return nil, err } - return obj.(*schedulingv1.PriorityClass), err + return obj.(*v1.PriorityClass), err } // List takes label and field selectors, and returns the list of PriorityClasses that match those selectors. -func (c *FakePriorityClasses) List(ctx context.Context, opts v1.ListOptions) (result *schedulingv1.PriorityClassList, err error) { +func (c *FakePriorityClasses) List(ctx context.Context, opts metav1.ListOptions) (result *v1.PriorityClassList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(priorityclassesResource, priorityclassesKind, opts), &schedulingv1.PriorityClassList{}) + Invokes(testing.NewRootListAction(priorityclassesResource, priorityclassesKind, opts), &v1.PriorityClassList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakePriorityClasses) List(ctx context.Context, opts v1.ListOptions) (re if label == nil { label = labels.Everything() } - list := &schedulingv1.PriorityClassList{ListMeta: obj.(*schedulingv1.PriorityClassList).ListMeta} - for _, item := range obj.(*schedulingv1.PriorityClassList).Items { + list := &v1.PriorityClassList{ListMeta: obj.(*v1.PriorityClassList).ListMeta} + for _, item := range obj.(*v1.PriorityClassList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,58 +73,58 @@ func (c *FakePriorityClasses) List(ctx context.Context, opts v1.ListOptions) (re } // Watch returns a watch.Interface that watches the requested priorityClasses. -func (c *FakePriorityClasses) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakePriorityClasses) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(priorityclassesResource, opts)) } // Create takes the representation of a priorityClass and creates it. Returns the server's representation of the priorityClass, and an error, if there is any. -func (c *FakePriorityClasses) Create(ctx context.Context, priorityClass *schedulingv1.PriorityClass, opts v1.CreateOptions) (result *schedulingv1.PriorityClass, err error) { +func (c *FakePriorityClasses) Create(ctx context.Context, priorityClass *v1.PriorityClass, opts metav1.CreateOptions) (result *v1.PriorityClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(priorityclassesResource, priorityClass), &schedulingv1.PriorityClass{}) + Invokes(testing.NewRootCreateAction(priorityclassesResource, priorityClass), &v1.PriorityClass{}) if obj == nil { return nil, err } - return obj.(*schedulingv1.PriorityClass), err + return obj.(*v1.PriorityClass), err } // Update takes the representation of a priorityClass and updates it. Returns the server's representation of the priorityClass, and an error, if there is any. -func (c *FakePriorityClasses) Update(ctx context.Context, priorityClass *schedulingv1.PriorityClass, opts v1.UpdateOptions) (result *schedulingv1.PriorityClass, err error) { +func (c *FakePriorityClasses) Update(ctx context.Context, priorityClass *v1.PriorityClass, opts metav1.UpdateOptions) (result *v1.PriorityClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(priorityclassesResource, priorityClass), &schedulingv1.PriorityClass{}) + Invokes(testing.NewRootUpdateAction(priorityclassesResource, priorityClass), &v1.PriorityClass{}) if obj == nil { return nil, err } - return obj.(*schedulingv1.PriorityClass), err + return obj.(*v1.PriorityClass), err } // Delete takes name of the priorityClass and deletes it. Returns an error if one occurs. -func (c *FakePriorityClasses) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakePriorityClasses) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(priorityclassesResource, name, opts), &schedulingv1.PriorityClass{}) + Invokes(testing.NewRootDeleteActionWithOptions(priorityclassesResource, name, opts), &v1.PriorityClass{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakePriorityClasses) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakePriorityClasses) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(priorityclassesResource, listOpts) - _, err := c.Fake.Invokes(action, &schedulingv1.PriorityClassList{}) + _, err := c.Fake.Invokes(action, &v1.PriorityClassList{}) return err } // Patch applies the patch and returns the patched priorityClass. -func (c *FakePriorityClasses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *schedulingv1.PriorityClass, err error) { +func (c *FakePriorityClasses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.PriorityClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(priorityclassesResource, name, pt, data, subresources...), &schedulingv1.PriorityClass{}) + Invokes(testing.NewRootPatchSubresourceAction(priorityclassesResource, name, pt, data, subresources...), &v1.PriorityClass{}) if obj == nil { return nil, err } - return obj.(*schedulingv1.PriorityClass), err + return obj.(*v1.PriorityClass), err } // Apply takes the given apply declarative configuration, applies it and returns the applied priorityClass. -func (c *FakePriorityClasses) Apply(ctx context.Context, priorityClass *applyconfigurationsschedulingv1.PriorityClassApplyConfiguration, opts v1.ApplyOptions) (result *schedulingv1.PriorityClass, err error) { +func (c *FakePriorityClasses) Apply(ctx context.Context, priorityClass *schedulingv1.PriorityClassApplyConfiguration, opts metav1.ApplyOptions) (result *v1.PriorityClass, err error) { if priorityClass == nil { return nil, fmt.Errorf("priorityClass provided to Apply must not be nil") } @@ -138,9 +137,9 @@ func (c *FakePriorityClasses) Apply(ctx context.Context, priorityClass *applycon return nil, fmt.Errorf("priorityClass.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(priorityclassesResource, *name, types.ApplyPatchType, data), &schedulingv1.PriorityClass{}) + Invokes(testing.NewRootPatchSubresourceAction(priorityclassesResource, *name, types.ApplyPatchType, data), &v1.PriorityClass{}) if obj == nil { return nil, err } - return obj.(*schedulingv1.PriorityClass), err + return obj.(*v1.PriorityClass), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/fake_priorityclass.go b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/fake_priorityclass.go index 32b6a11cb6..3c8404a725 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/fake_priorityclass.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1/fake/fake_priorityclass.go @@ -26,7 +26,6 @@ import ( v1alpha1 "k8s.io/api/scheduling/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" schedulingv1alpha1 "k8s.io/client-go/applyconfigurations/scheduling/v1alpha1" @@ -38,9 +37,9 @@ type FakePriorityClasses struct { Fake *FakeSchedulingV1alpha1 } -var priorityclassesResource = schema.GroupVersionResource{Group: "scheduling.k8s.io", Version: "v1alpha1", Resource: "priorityclasses"} +var priorityclassesResource = v1alpha1.SchemeGroupVersion.WithResource("priorityclasses") -var priorityclassesKind = schema.GroupVersionKind{Group: "scheduling.k8s.io", Version: "v1alpha1", Kind: "PriorityClass"} +var priorityclassesKind = v1alpha1.SchemeGroupVersion.WithKind("PriorityClass") // Get takes name of the priorityClass, and returns the corresponding priorityClass object, and an error if there is any. func (c *FakePriorityClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.PriorityClass, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1beta1/fake/fake_priorityclass.go b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1beta1/fake/fake_priorityclass.go index 8ff5a1bd61..4cf2e26c77 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1beta1/fake/fake_priorityclass.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/scheduling/v1beta1/fake/fake_priorityclass.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/scheduling/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" schedulingv1beta1 "k8s.io/client-go/applyconfigurations/scheduling/v1beta1" @@ -38,9 +37,9 @@ type FakePriorityClasses struct { Fake *FakeSchedulingV1beta1 } -var priorityclassesResource = schema.GroupVersionResource{Group: "scheduling.k8s.io", Version: "v1beta1", Resource: "priorityclasses"} +var priorityclassesResource = v1beta1.SchemeGroupVersion.WithResource("priorityclasses") -var priorityclassesKind = schema.GroupVersionKind{Group: "scheduling.k8s.io", Version: "v1beta1", Kind: "PriorityClass"} +var priorityclassesKind = v1beta1.SchemeGroupVersion.WithKind("PriorityClass") // Get takes name of the priorityClass, and returns the corresponding priorityClass object, and an error if there is any. func (c *FakePriorityClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.PriorityClass, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_csidriver.go b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_csidriver.go index 42df475dce..4983227376 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_csidriver.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_csidriver.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - storagev1 "k8s.io/api/storage/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsstoragev1 "k8s.io/client-go/applyconfigurations/storage/v1" + storagev1 "k8s.io/client-go/applyconfigurations/storage/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakeCSIDrivers struct { Fake *FakeStorageV1 } -var csidriversResource = schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1", Resource: "csidrivers"} +var csidriversResource = v1.SchemeGroupVersion.WithResource("csidrivers") -var csidriversKind = schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1", Kind: "CSIDriver"} +var csidriversKind = v1.SchemeGroupVersion.WithKind("CSIDriver") // Get takes name of the cSIDriver, and returns the corresponding cSIDriver object, and an error if there is any. -func (c *FakeCSIDrivers) Get(ctx context.Context, name string, options v1.GetOptions) (result *storagev1.CSIDriver, err error) { +func (c *FakeCSIDrivers) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CSIDriver, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(csidriversResource, name), &storagev1.CSIDriver{}) + Invokes(testing.NewRootGetAction(csidriversResource, name), &v1.CSIDriver{}) if obj == nil { return nil, err } - return obj.(*storagev1.CSIDriver), err + return obj.(*v1.CSIDriver), err } // List takes label and field selectors, and returns the list of CSIDrivers that match those selectors. -func (c *FakeCSIDrivers) List(ctx context.Context, opts v1.ListOptions) (result *storagev1.CSIDriverList, err error) { +func (c *FakeCSIDrivers) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CSIDriverList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(csidriversResource, csidriversKind, opts), &storagev1.CSIDriverList{}) + Invokes(testing.NewRootListAction(csidriversResource, csidriversKind, opts), &v1.CSIDriverList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakeCSIDrivers) List(ctx context.Context, opts v1.ListOptions) (result if label == nil { label = labels.Everything() } - list := &storagev1.CSIDriverList{ListMeta: obj.(*storagev1.CSIDriverList).ListMeta} - for _, item := range obj.(*storagev1.CSIDriverList).Items { + list := &v1.CSIDriverList{ListMeta: obj.(*v1.CSIDriverList).ListMeta} + for _, item := range obj.(*v1.CSIDriverList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,58 +73,58 @@ func (c *FakeCSIDrivers) List(ctx context.Context, opts v1.ListOptions) (result } // Watch returns a watch.Interface that watches the requested cSIDrivers. -func (c *FakeCSIDrivers) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeCSIDrivers) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(csidriversResource, opts)) } // Create takes the representation of a cSIDriver and creates it. Returns the server's representation of the cSIDriver, and an error, if there is any. -func (c *FakeCSIDrivers) Create(ctx context.Context, cSIDriver *storagev1.CSIDriver, opts v1.CreateOptions) (result *storagev1.CSIDriver, err error) { +func (c *FakeCSIDrivers) Create(ctx context.Context, cSIDriver *v1.CSIDriver, opts metav1.CreateOptions) (result *v1.CSIDriver, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(csidriversResource, cSIDriver), &storagev1.CSIDriver{}) + Invokes(testing.NewRootCreateAction(csidriversResource, cSIDriver), &v1.CSIDriver{}) if obj == nil { return nil, err } - return obj.(*storagev1.CSIDriver), err + return obj.(*v1.CSIDriver), err } // Update takes the representation of a cSIDriver and updates it. Returns the server's representation of the cSIDriver, and an error, if there is any. -func (c *FakeCSIDrivers) Update(ctx context.Context, cSIDriver *storagev1.CSIDriver, opts v1.UpdateOptions) (result *storagev1.CSIDriver, err error) { +func (c *FakeCSIDrivers) Update(ctx context.Context, cSIDriver *v1.CSIDriver, opts metav1.UpdateOptions) (result *v1.CSIDriver, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(csidriversResource, cSIDriver), &storagev1.CSIDriver{}) + Invokes(testing.NewRootUpdateAction(csidriversResource, cSIDriver), &v1.CSIDriver{}) if obj == nil { return nil, err } - return obj.(*storagev1.CSIDriver), err + return obj.(*v1.CSIDriver), err } // Delete takes name of the cSIDriver and deletes it. Returns an error if one occurs. -func (c *FakeCSIDrivers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeCSIDrivers) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(csidriversResource, name, opts), &storagev1.CSIDriver{}) + Invokes(testing.NewRootDeleteActionWithOptions(csidriversResource, name, opts), &v1.CSIDriver{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeCSIDrivers) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeCSIDrivers) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(csidriversResource, listOpts) - _, err := c.Fake.Invokes(action, &storagev1.CSIDriverList{}) + _, err := c.Fake.Invokes(action, &v1.CSIDriverList{}) return err } // Patch applies the patch and returns the patched cSIDriver. -func (c *FakeCSIDrivers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *storagev1.CSIDriver, err error) { +func (c *FakeCSIDrivers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CSIDriver, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(csidriversResource, name, pt, data, subresources...), &storagev1.CSIDriver{}) + Invokes(testing.NewRootPatchSubresourceAction(csidriversResource, name, pt, data, subresources...), &v1.CSIDriver{}) if obj == nil { return nil, err } - return obj.(*storagev1.CSIDriver), err + return obj.(*v1.CSIDriver), err } // Apply takes the given apply declarative configuration, applies it and returns the applied cSIDriver. -func (c *FakeCSIDrivers) Apply(ctx context.Context, cSIDriver *applyconfigurationsstoragev1.CSIDriverApplyConfiguration, opts v1.ApplyOptions) (result *storagev1.CSIDriver, err error) { +func (c *FakeCSIDrivers) Apply(ctx context.Context, cSIDriver *storagev1.CSIDriverApplyConfiguration, opts metav1.ApplyOptions) (result *v1.CSIDriver, err error) { if cSIDriver == nil { return nil, fmt.Errorf("cSIDriver provided to Apply must not be nil") } @@ -138,9 +137,9 @@ func (c *FakeCSIDrivers) Apply(ctx context.Context, cSIDriver *applyconfiguratio return nil, fmt.Errorf("cSIDriver.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(csidriversResource, *name, types.ApplyPatchType, data), &storagev1.CSIDriver{}) + Invokes(testing.NewRootPatchSubresourceAction(csidriversResource, *name, types.ApplyPatchType, data), &v1.CSIDriver{}) if obj == nil { return nil, err } - return obj.(*storagev1.CSIDriver), err + return obj.(*v1.CSIDriver), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_csinode.go b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_csinode.go index 4041d5e63f..0271a20f3d 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_csinode.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_csinode.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - storagev1 "k8s.io/api/storage/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsstoragev1 "k8s.io/client-go/applyconfigurations/storage/v1" + storagev1 "k8s.io/client-go/applyconfigurations/storage/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakeCSINodes struct { Fake *FakeStorageV1 } -var csinodesResource = schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1", Resource: "csinodes"} +var csinodesResource = v1.SchemeGroupVersion.WithResource("csinodes") -var csinodesKind = schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1", Kind: "CSINode"} +var csinodesKind = v1.SchemeGroupVersion.WithKind("CSINode") // Get takes name of the cSINode, and returns the corresponding cSINode object, and an error if there is any. -func (c *FakeCSINodes) Get(ctx context.Context, name string, options v1.GetOptions) (result *storagev1.CSINode, err error) { +func (c *FakeCSINodes) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CSINode, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(csinodesResource, name), &storagev1.CSINode{}) + Invokes(testing.NewRootGetAction(csinodesResource, name), &v1.CSINode{}) if obj == nil { return nil, err } - return obj.(*storagev1.CSINode), err + return obj.(*v1.CSINode), err } // List takes label and field selectors, and returns the list of CSINodes that match those selectors. -func (c *FakeCSINodes) List(ctx context.Context, opts v1.ListOptions) (result *storagev1.CSINodeList, err error) { +func (c *FakeCSINodes) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CSINodeList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(csinodesResource, csinodesKind, opts), &storagev1.CSINodeList{}) + Invokes(testing.NewRootListAction(csinodesResource, csinodesKind, opts), &v1.CSINodeList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakeCSINodes) List(ctx context.Context, opts v1.ListOptions) (result *s if label == nil { label = labels.Everything() } - list := &storagev1.CSINodeList{ListMeta: obj.(*storagev1.CSINodeList).ListMeta} - for _, item := range obj.(*storagev1.CSINodeList).Items { + list := &v1.CSINodeList{ListMeta: obj.(*v1.CSINodeList).ListMeta} + for _, item := range obj.(*v1.CSINodeList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,58 +73,58 @@ func (c *FakeCSINodes) List(ctx context.Context, opts v1.ListOptions) (result *s } // Watch returns a watch.Interface that watches the requested cSINodes. -func (c *FakeCSINodes) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeCSINodes) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(csinodesResource, opts)) } // Create takes the representation of a cSINode and creates it. Returns the server's representation of the cSINode, and an error, if there is any. -func (c *FakeCSINodes) Create(ctx context.Context, cSINode *storagev1.CSINode, opts v1.CreateOptions) (result *storagev1.CSINode, err error) { +func (c *FakeCSINodes) Create(ctx context.Context, cSINode *v1.CSINode, opts metav1.CreateOptions) (result *v1.CSINode, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(csinodesResource, cSINode), &storagev1.CSINode{}) + Invokes(testing.NewRootCreateAction(csinodesResource, cSINode), &v1.CSINode{}) if obj == nil { return nil, err } - return obj.(*storagev1.CSINode), err + return obj.(*v1.CSINode), err } // Update takes the representation of a cSINode and updates it. Returns the server's representation of the cSINode, and an error, if there is any. -func (c *FakeCSINodes) Update(ctx context.Context, cSINode *storagev1.CSINode, opts v1.UpdateOptions) (result *storagev1.CSINode, err error) { +func (c *FakeCSINodes) Update(ctx context.Context, cSINode *v1.CSINode, opts metav1.UpdateOptions) (result *v1.CSINode, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(csinodesResource, cSINode), &storagev1.CSINode{}) + Invokes(testing.NewRootUpdateAction(csinodesResource, cSINode), &v1.CSINode{}) if obj == nil { return nil, err } - return obj.(*storagev1.CSINode), err + return obj.(*v1.CSINode), err } // Delete takes name of the cSINode and deletes it. Returns an error if one occurs. -func (c *FakeCSINodes) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeCSINodes) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(csinodesResource, name, opts), &storagev1.CSINode{}) + Invokes(testing.NewRootDeleteActionWithOptions(csinodesResource, name, opts), &v1.CSINode{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeCSINodes) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeCSINodes) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(csinodesResource, listOpts) - _, err := c.Fake.Invokes(action, &storagev1.CSINodeList{}) + _, err := c.Fake.Invokes(action, &v1.CSINodeList{}) return err } // Patch applies the patch and returns the patched cSINode. -func (c *FakeCSINodes) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *storagev1.CSINode, err error) { +func (c *FakeCSINodes) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CSINode, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(csinodesResource, name, pt, data, subresources...), &storagev1.CSINode{}) + Invokes(testing.NewRootPatchSubresourceAction(csinodesResource, name, pt, data, subresources...), &v1.CSINode{}) if obj == nil { return nil, err } - return obj.(*storagev1.CSINode), err + return obj.(*v1.CSINode), err } // Apply takes the given apply declarative configuration, applies it and returns the applied cSINode. -func (c *FakeCSINodes) Apply(ctx context.Context, cSINode *applyconfigurationsstoragev1.CSINodeApplyConfiguration, opts v1.ApplyOptions) (result *storagev1.CSINode, err error) { +func (c *FakeCSINodes) Apply(ctx context.Context, cSINode *storagev1.CSINodeApplyConfiguration, opts metav1.ApplyOptions) (result *v1.CSINode, err error) { if cSINode == nil { return nil, fmt.Errorf("cSINode provided to Apply must not be nil") } @@ -138,9 +137,9 @@ func (c *FakeCSINodes) Apply(ctx context.Context, cSINode *applyconfigurationsst return nil, fmt.Errorf("cSINode.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(csinodesResource, *name, types.ApplyPatchType, data), &storagev1.CSINode{}) + Invokes(testing.NewRootPatchSubresourceAction(csinodesResource, *name, types.ApplyPatchType, data), &v1.CSINode{}) if obj == nil { return nil, err } - return obj.(*storagev1.CSINode), err + return obj.(*v1.CSINode), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_csistoragecapacity.go b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_csistoragecapacity.go index 40c4171c80..b12bbe3c15 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_csistoragecapacity.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_csistoragecapacity.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - storagev1 "k8s.io/api/storage/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsstoragev1 "k8s.io/client-go/applyconfigurations/storage/v1" + storagev1 "k8s.io/client-go/applyconfigurations/storage/v1" testing "k8s.io/client-go/testing" ) @@ -39,25 +38,25 @@ type FakeCSIStorageCapacities struct { ns string } -var csistoragecapacitiesResource = schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1", Resource: "csistoragecapacities"} +var csistoragecapacitiesResource = v1.SchemeGroupVersion.WithResource("csistoragecapacities") -var csistoragecapacitiesKind = schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1", Kind: "CSIStorageCapacity"} +var csistoragecapacitiesKind = v1.SchemeGroupVersion.WithKind("CSIStorageCapacity") // Get takes name of the cSIStorageCapacity, and returns the corresponding cSIStorageCapacity object, and an error if there is any. -func (c *FakeCSIStorageCapacities) Get(ctx context.Context, name string, options v1.GetOptions) (result *storagev1.CSIStorageCapacity, err error) { +func (c *FakeCSIStorageCapacities) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CSIStorageCapacity, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(csistoragecapacitiesResource, c.ns, name), &storagev1.CSIStorageCapacity{}) + Invokes(testing.NewGetAction(csistoragecapacitiesResource, c.ns, name), &v1.CSIStorageCapacity{}) if obj == nil { return nil, err } - return obj.(*storagev1.CSIStorageCapacity), err + return obj.(*v1.CSIStorageCapacity), err } // List takes label and field selectors, and returns the list of CSIStorageCapacities that match those selectors. -func (c *FakeCSIStorageCapacities) List(ctx context.Context, opts v1.ListOptions) (result *storagev1.CSIStorageCapacityList, err error) { +func (c *FakeCSIStorageCapacities) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CSIStorageCapacityList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(csistoragecapacitiesResource, csistoragecapacitiesKind, c.ns, opts), &storagev1.CSIStorageCapacityList{}) + Invokes(testing.NewListAction(csistoragecapacitiesResource, csistoragecapacitiesKind, c.ns, opts), &v1.CSIStorageCapacityList{}) if obj == nil { return nil, err @@ -67,8 +66,8 @@ func (c *FakeCSIStorageCapacities) List(ctx context.Context, opts v1.ListOptions if label == nil { label = labels.Everything() } - list := &storagev1.CSIStorageCapacityList{ListMeta: obj.(*storagev1.CSIStorageCapacityList).ListMeta} - for _, item := range obj.(*storagev1.CSIStorageCapacityList).Items { + list := &v1.CSIStorageCapacityList{ListMeta: obj.(*v1.CSIStorageCapacityList).ListMeta} + for _, item := range obj.(*v1.CSIStorageCapacityList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -77,63 +76,63 @@ func (c *FakeCSIStorageCapacities) List(ctx context.Context, opts v1.ListOptions } // Watch returns a watch.Interface that watches the requested cSIStorageCapacities. -func (c *FakeCSIStorageCapacities) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeCSIStorageCapacities) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewWatchAction(csistoragecapacitiesResource, c.ns, opts)) } // Create takes the representation of a cSIStorageCapacity and creates it. Returns the server's representation of the cSIStorageCapacity, and an error, if there is any. -func (c *FakeCSIStorageCapacities) Create(ctx context.Context, cSIStorageCapacity *storagev1.CSIStorageCapacity, opts v1.CreateOptions) (result *storagev1.CSIStorageCapacity, err error) { +func (c *FakeCSIStorageCapacities) Create(ctx context.Context, cSIStorageCapacity *v1.CSIStorageCapacity, opts metav1.CreateOptions) (result *v1.CSIStorageCapacity, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(csistoragecapacitiesResource, c.ns, cSIStorageCapacity), &storagev1.CSIStorageCapacity{}) + Invokes(testing.NewCreateAction(csistoragecapacitiesResource, c.ns, cSIStorageCapacity), &v1.CSIStorageCapacity{}) if obj == nil { return nil, err } - return obj.(*storagev1.CSIStorageCapacity), err + return obj.(*v1.CSIStorageCapacity), err } // Update takes the representation of a cSIStorageCapacity and updates it. Returns the server's representation of the cSIStorageCapacity, and an error, if there is any. -func (c *FakeCSIStorageCapacities) Update(ctx context.Context, cSIStorageCapacity *storagev1.CSIStorageCapacity, opts v1.UpdateOptions) (result *storagev1.CSIStorageCapacity, err error) { +func (c *FakeCSIStorageCapacities) Update(ctx context.Context, cSIStorageCapacity *v1.CSIStorageCapacity, opts metav1.UpdateOptions) (result *v1.CSIStorageCapacity, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(csistoragecapacitiesResource, c.ns, cSIStorageCapacity), &storagev1.CSIStorageCapacity{}) + Invokes(testing.NewUpdateAction(csistoragecapacitiesResource, c.ns, cSIStorageCapacity), &v1.CSIStorageCapacity{}) if obj == nil { return nil, err } - return obj.(*storagev1.CSIStorageCapacity), err + return obj.(*v1.CSIStorageCapacity), err } // Delete takes name of the cSIStorageCapacity and deletes it. Returns an error if one occurs. -func (c *FakeCSIStorageCapacities) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeCSIStorageCapacities) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(csistoragecapacitiesResource, c.ns, name, opts), &storagev1.CSIStorageCapacity{}) + Invokes(testing.NewDeleteActionWithOptions(csistoragecapacitiesResource, c.ns, name, opts), &v1.CSIStorageCapacity{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeCSIStorageCapacities) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeCSIStorageCapacities) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewDeleteCollectionAction(csistoragecapacitiesResource, c.ns, listOpts) - _, err := c.Fake.Invokes(action, &storagev1.CSIStorageCapacityList{}) + _, err := c.Fake.Invokes(action, &v1.CSIStorageCapacityList{}) return err } // Patch applies the patch and returns the patched cSIStorageCapacity. -func (c *FakeCSIStorageCapacities) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *storagev1.CSIStorageCapacity, err error) { +func (c *FakeCSIStorageCapacities) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CSIStorageCapacity, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(csistoragecapacitiesResource, c.ns, name, pt, data, subresources...), &storagev1.CSIStorageCapacity{}) + Invokes(testing.NewPatchSubresourceAction(csistoragecapacitiesResource, c.ns, name, pt, data, subresources...), &v1.CSIStorageCapacity{}) if obj == nil { return nil, err } - return obj.(*storagev1.CSIStorageCapacity), err + return obj.(*v1.CSIStorageCapacity), err } // Apply takes the given apply declarative configuration, applies it and returns the applied cSIStorageCapacity. -func (c *FakeCSIStorageCapacities) Apply(ctx context.Context, cSIStorageCapacity *applyconfigurationsstoragev1.CSIStorageCapacityApplyConfiguration, opts v1.ApplyOptions) (result *storagev1.CSIStorageCapacity, err error) { +func (c *FakeCSIStorageCapacities) Apply(ctx context.Context, cSIStorageCapacity *storagev1.CSIStorageCapacityApplyConfiguration, opts metav1.ApplyOptions) (result *v1.CSIStorageCapacity, err error) { if cSIStorageCapacity == nil { return nil, fmt.Errorf("cSIStorageCapacity provided to Apply must not be nil") } @@ -146,10 +145,10 @@ func (c *FakeCSIStorageCapacities) Apply(ctx context.Context, cSIStorageCapacity return nil, fmt.Errorf("cSIStorageCapacity.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(csistoragecapacitiesResource, c.ns, *name, types.ApplyPatchType, data), &storagev1.CSIStorageCapacity{}) + Invokes(testing.NewPatchSubresourceAction(csistoragecapacitiesResource, c.ns, *name, types.ApplyPatchType, data), &v1.CSIStorageCapacity{}) if obj == nil { return nil, err } - return obj.(*storagev1.CSIStorageCapacity), err + return obj.(*v1.CSIStorageCapacity), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_storageclass.go b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_storageclass.go index 60895be5b7..e232f4c8d7 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_storageclass.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_storageclass.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - storagev1 "k8s.io/api/storage/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsstoragev1 "k8s.io/client-go/applyconfigurations/storage/v1" + storagev1 "k8s.io/client-go/applyconfigurations/storage/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakeStorageClasses struct { Fake *FakeStorageV1 } -var storageclassesResource = schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1", Resource: "storageclasses"} +var storageclassesResource = v1.SchemeGroupVersion.WithResource("storageclasses") -var storageclassesKind = schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1", Kind: "StorageClass"} +var storageclassesKind = v1.SchemeGroupVersion.WithKind("StorageClass") // Get takes name of the storageClass, and returns the corresponding storageClass object, and an error if there is any. -func (c *FakeStorageClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *storagev1.StorageClass, err error) { +func (c *FakeStorageClasses) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.StorageClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(storageclassesResource, name), &storagev1.StorageClass{}) + Invokes(testing.NewRootGetAction(storageclassesResource, name), &v1.StorageClass{}) if obj == nil { return nil, err } - return obj.(*storagev1.StorageClass), err + return obj.(*v1.StorageClass), err } // List takes label and field selectors, and returns the list of StorageClasses that match those selectors. -func (c *FakeStorageClasses) List(ctx context.Context, opts v1.ListOptions) (result *storagev1.StorageClassList, err error) { +func (c *FakeStorageClasses) List(ctx context.Context, opts metav1.ListOptions) (result *v1.StorageClassList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(storageclassesResource, storageclassesKind, opts), &storagev1.StorageClassList{}) + Invokes(testing.NewRootListAction(storageclassesResource, storageclassesKind, opts), &v1.StorageClassList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakeStorageClasses) List(ctx context.Context, opts v1.ListOptions) (res if label == nil { label = labels.Everything() } - list := &storagev1.StorageClassList{ListMeta: obj.(*storagev1.StorageClassList).ListMeta} - for _, item := range obj.(*storagev1.StorageClassList).Items { + list := &v1.StorageClassList{ListMeta: obj.(*v1.StorageClassList).ListMeta} + for _, item := range obj.(*v1.StorageClassList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,58 +73,58 @@ func (c *FakeStorageClasses) List(ctx context.Context, opts v1.ListOptions) (res } // Watch returns a watch.Interface that watches the requested storageClasses. -func (c *FakeStorageClasses) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeStorageClasses) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(storageclassesResource, opts)) } // Create takes the representation of a storageClass and creates it. Returns the server's representation of the storageClass, and an error, if there is any. -func (c *FakeStorageClasses) Create(ctx context.Context, storageClass *storagev1.StorageClass, opts v1.CreateOptions) (result *storagev1.StorageClass, err error) { +func (c *FakeStorageClasses) Create(ctx context.Context, storageClass *v1.StorageClass, opts metav1.CreateOptions) (result *v1.StorageClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(storageclassesResource, storageClass), &storagev1.StorageClass{}) + Invokes(testing.NewRootCreateAction(storageclassesResource, storageClass), &v1.StorageClass{}) if obj == nil { return nil, err } - return obj.(*storagev1.StorageClass), err + return obj.(*v1.StorageClass), err } // Update takes the representation of a storageClass and updates it. Returns the server's representation of the storageClass, and an error, if there is any. -func (c *FakeStorageClasses) Update(ctx context.Context, storageClass *storagev1.StorageClass, opts v1.UpdateOptions) (result *storagev1.StorageClass, err error) { +func (c *FakeStorageClasses) Update(ctx context.Context, storageClass *v1.StorageClass, opts metav1.UpdateOptions) (result *v1.StorageClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(storageclassesResource, storageClass), &storagev1.StorageClass{}) + Invokes(testing.NewRootUpdateAction(storageclassesResource, storageClass), &v1.StorageClass{}) if obj == nil { return nil, err } - return obj.(*storagev1.StorageClass), err + return obj.(*v1.StorageClass), err } // Delete takes name of the storageClass and deletes it. Returns an error if one occurs. -func (c *FakeStorageClasses) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeStorageClasses) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(storageclassesResource, name, opts), &storagev1.StorageClass{}) + Invokes(testing.NewRootDeleteActionWithOptions(storageclassesResource, name, opts), &v1.StorageClass{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeStorageClasses) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeStorageClasses) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(storageclassesResource, listOpts) - _, err := c.Fake.Invokes(action, &storagev1.StorageClassList{}) + _, err := c.Fake.Invokes(action, &v1.StorageClassList{}) return err } // Patch applies the patch and returns the patched storageClass. -func (c *FakeStorageClasses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *storagev1.StorageClass, err error) { +func (c *FakeStorageClasses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.StorageClass, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(storageclassesResource, name, pt, data, subresources...), &storagev1.StorageClass{}) + Invokes(testing.NewRootPatchSubresourceAction(storageclassesResource, name, pt, data, subresources...), &v1.StorageClass{}) if obj == nil { return nil, err } - return obj.(*storagev1.StorageClass), err + return obj.(*v1.StorageClass), err } // Apply takes the given apply declarative configuration, applies it and returns the applied storageClass. -func (c *FakeStorageClasses) Apply(ctx context.Context, storageClass *applyconfigurationsstoragev1.StorageClassApplyConfiguration, opts v1.ApplyOptions) (result *storagev1.StorageClass, err error) { +func (c *FakeStorageClasses) Apply(ctx context.Context, storageClass *storagev1.StorageClassApplyConfiguration, opts metav1.ApplyOptions) (result *v1.StorageClass, err error) { if storageClass == nil { return nil, fmt.Errorf("storageClass provided to Apply must not be nil") } @@ -138,9 +137,9 @@ func (c *FakeStorageClasses) Apply(ctx context.Context, storageClass *applyconfi return nil, fmt.Errorf("storageClass.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(storageclassesResource, *name, types.ApplyPatchType, data), &storagev1.StorageClass{}) + Invokes(testing.NewRootPatchSubresourceAction(storageclassesResource, *name, types.ApplyPatchType, data), &v1.StorageClass{}) if obj == nil { return nil, err } - return obj.(*storagev1.StorageClass), err + return obj.(*v1.StorageClass), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_volumeattachment.go b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_volumeattachment.go index e48943f8ef..3f5f2aec57 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_volumeattachment.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1/fake/fake_volumeattachment.go @@ -23,13 +23,12 @@ import ( json "encoding/json" "fmt" - storagev1 "k8s.io/api/storage/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - applyconfigurationsstoragev1 "k8s.io/client-go/applyconfigurations/storage/v1" + storagev1 "k8s.io/client-go/applyconfigurations/storage/v1" testing "k8s.io/client-go/testing" ) @@ -38,24 +37,24 @@ type FakeVolumeAttachments struct { Fake *FakeStorageV1 } -var volumeattachmentsResource = schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1", Resource: "volumeattachments"} +var volumeattachmentsResource = v1.SchemeGroupVersion.WithResource("volumeattachments") -var volumeattachmentsKind = schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1", Kind: "VolumeAttachment"} +var volumeattachmentsKind = v1.SchemeGroupVersion.WithKind("VolumeAttachment") // Get takes name of the volumeAttachment, and returns the corresponding volumeAttachment object, and an error if there is any. -func (c *FakeVolumeAttachments) Get(ctx context.Context, name string, options v1.GetOptions) (result *storagev1.VolumeAttachment, err error) { +func (c *FakeVolumeAttachments) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.VolumeAttachment, err error) { obj, err := c.Fake. - Invokes(testing.NewRootGetAction(volumeattachmentsResource, name), &storagev1.VolumeAttachment{}) + Invokes(testing.NewRootGetAction(volumeattachmentsResource, name), &v1.VolumeAttachment{}) if obj == nil { return nil, err } - return obj.(*storagev1.VolumeAttachment), err + return obj.(*v1.VolumeAttachment), err } // List takes label and field selectors, and returns the list of VolumeAttachments that match those selectors. -func (c *FakeVolumeAttachments) List(ctx context.Context, opts v1.ListOptions) (result *storagev1.VolumeAttachmentList, err error) { +func (c *FakeVolumeAttachments) List(ctx context.Context, opts metav1.ListOptions) (result *v1.VolumeAttachmentList, err error) { obj, err := c.Fake. - Invokes(testing.NewRootListAction(volumeattachmentsResource, volumeattachmentsKind, opts), &storagev1.VolumeAttachmentList{}) + Invokes(testing.NewRootListAction(volumeattachmentsResource, volumeattachmentsKind, opts), &v1.VolumeAttachmentList{}) if obj == nil { return nil, err } @@ -64,8 +63,8 @@ func (c *FakeVolumeAttachments) List(ctx context.Context, opts v1.ListOptions) ( if label == nil { label = labels.Everything() } - list := &storagev1.VolumeAttachmentList{ListMeta: obj.(*storagev1.VolumeAttachmentList).ListMeta} - for _, item := range obj.(*storagev1.VolumeAttachmentList).Items { + list := &v1.VolumeAttachmentList{ListMeta: obj.(*v1.VolumeAttachmentList).ListMeta} + for _, item := range obj.(*v1.VolumeAttachmentList).Items { if label.Matches(labels.Set(item.Labels)) { list.Items = append(list.Items, item) } @@ -74,69 +73,69 @@ func (c *FakeVolumeAttachments) List(ctx context.Context, opts v1.ListOptions) ( } // Watch returns a watch.Interface that watches the requested volumeAttachments. -func (c *FakeVolumeAttachments) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { +func (c *FakeVolumeAttachments) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { return c.Fake. InvokesWatch(testing.NewRootWatchAction(volumeattachmentsResource, opts)) } // Create takes the representation of a volumeAttachment and creates it. Returns the server's representation of the volumeAttachment, and an error, if there is any. -func (c *FakeVolumeAttachments) Create(ctx context.Context, volumeAttachment *storagev1.VolumeAttachment, opts v1.CreateOptions) (result *storagev1.VolumeAttachment, err error) { +func (c *FakeVolumeAttachments) Create(ctx context.Context, volumeAttachment *v1.VolumeAttachment, opts metav1.CreateOptions) (result *v1.VolumeAttachment, err error) { obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(volumeattachmentsResource, volumeAttachment), &storagev1.VolumeAttachment{}) + Invokes(testing.NewRootCreateAction(volumeattachmentsResource, volumeAttachment), &v1.VolumeAttachment{}) if obj == nil { return nil, err } - return obj.(*storagev1.VolumeAttachment), err + return obj.(*v1.VolumeAttachment), err } // Update takes the representation of a volumeAttachment and updates it. Returns the server's representation of the volumeAttachment, and an error, if there is any. -func (c *FakeVolumeAttachments) Update(ctx context.Context, volumeAttachment *storagev1.VolumeAttachment, opts v1.UpdateOptions) (result *storagev1.VolumeAttachment, err error) { +func (c *FakeVolumeAttachments) Update(ctx context.Context, volumeAttachment *v1.VolumeAttachment, opts metav1.UpdateOptions) (result *v1.VolumeAttachment, err error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(volumeattachmentsResource, volumeAttachment), &storagev1.VolumeAttachment{}) + Invokes(testing.NewRootUpdateAction(volumeattachmentsResource, volumeAttachment), &v1.VolumeAttachment{}) if obj == nil { return nil, err } - return obj.(*storagev1.VolumeAttachment), err + return obj.(*v1.VolumeAttachment), 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 *FakeVolumeAttachments) UpdateStatus(ctx context.Context, volumeAttachment *storagev1.VolumeAttachment, opts v1.UpdateOptions) (*storagev1.VolumeAttachment, error) { +func (c *FakeVolumeAttachments) UpdateStatus(ctx context.Context, volumeAttachment *v1.VolumeAttachment, opts metav1.UpdateOptions) (*v1.VolumeAttachment, error) { obj, err := c.Fake. - Invokes(testing.NewRootUpdateSubresourceAction(volumeattachmentsResource, "status", volumeAttachment), &storagev1.VolumeAttachment{}) + Invokes(testing.NewRootUpdateSubresourceAction(volumeattachmentsResource, "status", volumeAttachment), &v1.VolumeAttachment{}) if obj == nil { return nil, err } - return obj.(*storagev1.VolumeAttachment), err + return obj.(*v1.VolumeAttachment), err } // Delete takes name of the volumeAttachment and deletes it. Returns an error if one occurs. -func (c *FakeVolumeAttachments) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { +func (c *FakeVolumeAttachments) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(volumeattachmentsResource, name, opts), &storagev1.VolumeAttachment{}) + Invokes(testing.NewRootDeleteActionWithOptions(volumeattachmentsResource, name, opts), &v1.VolumeAttachment{}) return err } // DeleteCollection deletes a collection of objects. -func (c *FakeVolumeAttachments) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { +func (c *FakeVolumeAttachments) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { action := testing.NewRootDeleteCollectionAction(volumeattachmentsResource, listOpts) - _, err := c.Fake.Invokes(action, &storagev1.VolumeAttachmentList{}) + _, err := c.Fake.Invokes(action, &v1.VolumeAttachmentList{}) return err } // Patch applies the patch and returns the patched volumeAttachment. -func (c *FakeVolumeAttachments) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *storagev1.VolumeAttachment, err error) { +func (c *FakeVolumeAttachments) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VolumeAttachment, err error) { obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(volumeattachmentsResource, name, pt, data, subresources...), &storagev1.VolumeAttachment{}) + Invokes(testing.NewRootPatchSubresourceAction(volumeattachmentsResource, name, pt, data, subresources...), &v1.VolumeAttachment{}) if obj == nil { return nil, err } - return obj.(*storagev1.VolumeAttachment), err + return obj.(*v1.VolumeAttachment), err } // Apply takes the given apply declarative configuration, applies it and returns the applied volumeAttachment. -func (c *FakeVolumeAttachments) Apply(ctx context.Context, volumeAttachment *applyconfigurationsstoragev1.VolumeAttachmentApplyConfiguration, opts v1.ApplyOptions) (result *storagev1.VolumeAttachment, err error) { +func (c *FakeVolumeAttachments) Apply(ctx context.Context, volumeAttachment *storagev1.VolumeAttachmentApplyConfiguration, opts metav1.ApplyOptions) (result *v1.VolumeAttachment, err error) { if volumeAttachment == nil { return nil, fmt.Errorf("volumeAttachment provided to Apply must not be nil") } @@ -149,16 +148,16 @@ func (c *FakeVolumeAttachments) Apply(ctx context.Context, volumeAttachment *app return nil, fmt.Errorf("volumeAttachment.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(volumeattachmentsResource, *name, types.ApplyPatchType, data), &storagev1.VolumeAttachment{}) + Invokes(testing.NewRootPatchSubresourceAction(volumeattachmentsResource, *name, types.ApplyPatchType, data), &v1.VolumeAttachment{}) if obj == nil { return nil, err } - return obj.(*storagev1.VolumeAttachment), err + return obj.(*v1.VolumeAttachment), err } // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *FakeVolumeAttachments) ApplyStatus(ctx context.Context, volumeAttachment *applyconfigurationsstoragev1.VolumeAttachmentApplyConfiguration, opts v1.ApplyOptions) (result *storagev1.VolumeAttachment, err error) { +func (c *FakeVolumeAttachments) ApplyStatus(ctx context.Context, volumeAttachment *storagev1.VolumeAttachmentApplyConfiguration, opts metav1.ApplyOptions) (result *v1.VolumeAttachment, err error) { if volumeAttachment == nil { return nil, fmt.Errorf("volumeAttachment provided to Apply must not be nil") } @@ -171,9 +170,9 @@ func (c *FakeVolumeAttachments) ApplyStatus(ctx context.Context, volumeAttachmen return nil, fmt.Errorf("volumeAttachment.Name must be provided to Apply") } obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(volumeattachmentsResource, *name, types.ApplyPatchType, data, "status"), &storagev1.VolumeAttachment{}) + Invokes(testing.NewRootPatchSubresourceAction(volumeattachmentsResource, *name, types.ApplyPatchType, data, "status"), &v1.VolumeAttachment{}) if obj == nil { return nil, err } - return obj.(*storagev1.VolumeAttachment), err + return obj.(*v1.VolumeAttachment), err } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1alpha1/fake/fake_csistoragecapacity.go b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1alpha1/fake/fake_csistoragecapacity.go index f56ed7895a..c1614cda7d 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1alpha1/fake/fake_csistoragecapacity.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1alpha1/fake/fake_csistoragecapacity.go @@ -26,7 +26,6 @@ import ( v1alpha1 "k8s.io/api/storage/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" storagev1alpha1 "k8s.io/client-go/applyconfigurations/storage/v1alpha1" @@ -39,9 +38,9 @@ type FakeCSIStorageCapacities struct { ns string } -var csistoragecapacitiesResource = schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1alpha1", Resource: "csistoragecapacities"} +var csistoragecapacitiesResource = v1alpha1.SchemeGroupVersion.WithResource("csistoragecapacities") -var csistoragecapacitiesKind = schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1alpha1", Kind: "CSIStorageCapacity"} +var csistoragecapacitiesKind = v1alpha1.SchemeGroupVersion.WithKind("CSIStorageCapacity") // Get takes name of the cSIStorageCapacity, and returns the corresponding cSIStorageCapacity object, and an error if there is any. func (c *FakeCSIStorageCapacities) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.CSIStorageCapacity, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1alpha1/fake/fake_volumeattachment.go b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1alpha1/fake/fake_volumeattachment.go index eb6ec7983b..9725d6d10b 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1alpha1/fake/fake_volumeattachment.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1alpha1/fake/fake_volumeattachment.go @@ -26,7 +26,6 @@ import ( v1alpha1 "k8s.io/api/storage/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" storagev1alpha1 "k8s.io/client-go/applyconfigurations/storage/v1alpha1" @@ -38,9 +37,9 @@ type FakeVolumeAttachments struct { Fake *FakeStorageV1alpha1 } -var volumeattachmentsResource = schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1alpha1", Resource: "volumeattachments"} +var volumeattachmentsResource = v1alpha1.SchemeGroupVersion.WithResource("volumeattachments") -var volumeattachmentsKind = schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1alpha1", Kind: "VolumeAttachment"} +var volumeattachmentsKind = v1alpha1.SchemeGroupVersion.WithKind("VolumeAttachment") // Get takes name of the volumeAttachment, and returns the corresponding volumeAttachment object, and an error if there is any. func (c *FakeVolumeAttachments) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.VolumeAttachment, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_csidriver.go b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_csidriver.go index c65fa74222..4257aa6183 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_csidriver.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_csidriver.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/storage/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" storagev1beta1 "k8s.io/client-go/applyconfigurations/storage/v1beta1" @@ -38,9 +37,9 @@ type FakeCSIDrivers struct { Fake *FakeStorageV1beta1 } -var csidriversResource = schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1beta1", Resource: "csidrivers"} +var csidriversResource = v1beta1.SchemeGroupVersion.WithResource("csidrivers") -var csidriversKind = schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1beta1", Kind: "CSIDriver"} +var csidriversKind = v1beta1.SchemeGroupVersion.WithKind("CSIDriver") // Get takes name of the cSIDriver, and returns the corresponding cSIDriver object, and an error if there is any. func (c *FakeCSIDrivers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.CSIDriver, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_csinode.go b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_csinode.go index 1ffd49b3ab..d38c104bc1 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_csinode.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_csinode.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/storage/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" storagev1beta1 "k8s.io/client-go/applyconfigurations/storage/v1beta1" @@ -38,9 +37,9 @@ type FakeCSINodes struct { Fake *FakeStorageV1beta1 } -var csinodesResource = schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1beta1", Resource: "csinodes"} +var csinodesResource = v1beta1.SchemeGroupVersion.WithResource("csinodes") -var csinodesKind = schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1beta1", Kind: "CSINode"} +var csinodesKind = v1beta1.SchemeGroupVersion.WithKind("CSINode") // Get takes name of the cSINode, and returns the corresponding cSINode object, and an error if there is any. func (c *FakeCSINodes) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.CSINode, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_csistoragecapacity.go b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_csistoragecapacity.go index 1715884d1b..d7bbb614b2 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_csistoragecapacity.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_csistoragecapacity.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/storage/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" storagev1beta1 "k8s.io/client-go/applyconfigurations/storage/v1beta1" @@ -39,9 +38,9 @@ type FakeCSIStorageCapacities struct { ns string } -var csistoragecapacitiesResource = schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1beta1", Resource: "csistoragecapacities"} +var csistoragecapacitiesResource = v1beta1.SchemeGroupVersion.WithResource("csistoragecapacities") -var csistoragecapacitiesKind = schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1beta1", Kind: "CSIStorageCapacity"} +var csistoragecapacitiesKind = v1beta1.SchemeGroupVersion.WithKind("CSIStorageCapacity") // Get takes name of the cSIStorageCapacity, and returns the corresponding cSIStorageCapacity object, and an error if there is any. func (c *FakeCSIStorageCapacities) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.CSIStorageCapacity, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_storageclass.go b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_storageclass.go index f929c55f8d..869e58b4f7 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_storageclass.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_storageclass.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/storage/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" storagev1beta1 "k8s.io/client-go/applyconfigurations/storage/v1beta1" @@ -38,9 +37,9 @@ type FakeStorageClasses struct { Fake *FakeStorageV1beta1 } -var storageclassesResource = schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1beta1", Resource: "storageclasses"} +var storageclassesResource = v1beta1.SchemeGroupVersion.WithResource("storageclasses") -var storageclassesKind = schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1beta1", Kind: "StorageClass"} +var storageclassesKind = v1beta1.SchemeGroupVersion.WithKind("StorageClass") // Get takes name of the storageClass, and returns the corresponding storageClass object, and an error if there is any. func (c *FakeStorageClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.StorageClass, err error) { diff --git a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_volumeattachment.go b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_volumeattachment.go index 81df877691..e2b4a2eb1b 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_volumeattachment.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake/fake_volumeattachment.go @@ -26,7 +26,6 @@ import ( v1beta1 "k8s.io/api/storage/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" storagev1beta1 "k8s.io/client-go/applyconfigurations/storage/v1beta1" @@ -38,9 +37,9 @@ type FakeVolumeAttachments struct { Fake *FakeStorageV1beta1 } -var volumeattachmentsResource = schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1beta1", Resource: "volumeattachments"} +var volumeattachmentsResource = v1beta1.SchemeGroupVersion.WithResource("volumeattachments") -var volumeattachmentsKind = schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1beta1", Kind: "VolumeAttachment"} +var volumeattachmentsKind = v1beta1.SchemeGroupVersion.WithKind("VolumeAttachment") // Get takes name of the volumeAttachment, and returns the corresponding volumeAttachment object, and an error if there is any. func (c *FakeVolumeAttachments) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.VolumeAttachment, err error) { diff --git a/vendor/k8s.io/client-go/listers/certificates/v1alpha1/clustertrustbundle.go b/vendor/k8s.io/client-go/listers/certificates/v1alpha1/clustertrustbundle.go new file mode 100644 index 0000000000..b8049a7618 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/certificates/v1alpha1/clustertrustbundle.go @@ -0,0 +1,68 @@ +/* +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 v1alpha1 + +import ( + v1alpha1 "k8s.io/api/certificates/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ClusterTrustBundleLister helps list ClusterTrustBundles. +// All objects returned here must be treated as read-only. +type ClusterTrustBundleLister interface { + // List lists all ClusterTrustBundles in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.ClusterTrustBundle, err error) + // Get retrieves the ClusterTrustBundle from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.ClusterTrustBundle, error) + ClusterTrustBundleListerExpansion +} + +// clusterTrustBundleLister implements the ClusterTrustBundleLister interface. +type clusterTrustBundleLister struct { + indexer cache.Indexer +} + +// NewClusterTrustBundleLister returns a new ClusterTrustBundleLister. +func NewClusterTrustBundleLister(indexer cache.Indexer) ClusterTrustBundleLister { + return &clusterTrustBundleLister{indexer: indexer} +} + +// List lists all ClusterTrustBundles in the indexer. +func (s *clusterTrustBundleLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterTrustBundle, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.ClusterTrustBundle)) + }) + return ret, err +} + +// Get retrieves the ClusterTrustBundle from the index for a given name. +func (s *clusterTrustBundleLister) Get(name string) (*v1alpha1.ClusterTrustBundle, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("clustertrustbundle"), name) + } + return obj.(*v1alpha1.ClusterTrustBundle), nil +} diff --git a/vendor/k8s.io/client-go/listers/certificates/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/certificates/v1alpha1/expansion_generated.go new file mode 100644 index 0000000000..d77258cb2d --- /dev/null +++ b/vendor/k8s.io/client-go/listers/certificates/v1alpha1/expansion_generated.go @@ -0,0 +1,23 @@ +/* +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 v1alpha1 + +// ClusterTrustBundleListerExpansion allows custom methods to be added to +// ClusterTrustBundleLister. +type ClusterTrustBundleListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/extensions/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/extensions/v1beta1/expansion_generated.go index 5599219d9e..4c65dbf764 100644 --- a/vendor/k8s.io/client-go/listers/extensions/v1beta1/expansion_generated.go +++ b/vendor/k8s.io/client-go/listers/extensions/v1beta1/expansion_generated.go @@ -41,7 +41,3 @@ type NetworkPolicyListerExpansion interface{} // NetworkPolicyNamespaceListerExpansion allows custom methods to be added to // NetworkPolicyNamespaceLister. type NetworkPolicyNamespaceListerExpansion interface{} - -// PodSecurityPolicyListerExpansion allows custom methods to be added to -// PodSecurityPolicyLister. -type PodSecurityPolicyListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/extensions/v1beta1/podsecuritypolicy.go b/vendor/k8s.io/client-go/listers/extensions/v1beta1/podsecuritypolicy.go deleted file mode 100644 index 5f6a8c0360..0000000000 --- a/vendor/k8s.io/client-go/listers/extensions/v1beta1/podsecuritypolicy.go +++ /dev/null @@ -1,68 +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" -) - -// PodSecurityPolicyLister helps list PodSecurityPolicies. -// All objects returned here must be treated as read-only. -type PodSecurityPolicyLister interface { - // List lists all PodSecurityPolicies in the indexer. - // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1beta1.PodSecurityPolicy, err error) - // Get retrieves the PodSecurityPolicy from the index for a given name. - // Objects returned here must be treated as read-only. - Get(name string) (*v1beta1.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 []*v1beta1.PodSecurityPolicy, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1beta1.PodSecurityPolicy)) - }) - return ret, err -} - -// Get retrieves the PodSecurityPolicy from the index for a given name. -func (s *podSecurityPolicyLister) Get(name string) (*v1beta1.PodSecurityPolicy, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1beta1.Resource("podsecuritypolicy"), name) - } - return obj.(*v1beta1.PodSecurityPolicy), nil -} diff --git a/vendor/k8s.io/client-go/listers/networking/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/networking/v1alpha1/expansion_generated.go index cdc328231a..d57b71b005 100644 --- a/vendor/k8s.io/client-go/listers/networking/v1alpha1/expansion_generated.go +++ b/vendor/k8s.io/client-go/listers/networking/v1alpha1/expansion_generated.go @@ -21,3 +21,7 @@ package v1alpha1 // ClusterCIDRListerExpansion allows custom methods to be added to // ClusterCIDRLister. type ClusterCIDRListerExpansion interface{} + +// IPAddressListerExpansion allows custom methods to be added to +// IPAddressLister. +type IPAddressListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/networking/v1alpha1/ipaddress.go b/vendor/k8s.io/client-go/listers/networking/v1alpha1/ipaddress.go new file mode 100644 index 0000000000..b3dfe27971 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/networking/v1alpha1/ipaddress.go @@ -0,0 +1,68 @@ +/* +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 v1alpha1 + +import ( + v1alpha1 "k8s.io/api/networking/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// IPAddressLister helps list IPAddresses. +// All objects returned here must be treated as read-only. +type IPAddressLister interface { + // List lists all IPAddresses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.IPAddress, err error) + // Get retrieves the IPAddress from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.IPAddress, error) + IPAddressListerExpansion +} + +// iPAddressLister implements the IPAddressLister interface. +type iPAddressLister struct { + indexer cache.Indexer +} + +// NewIPAddressLister returns a new IPAddressLister. +func NewIPAddressLister(indexer cache.Indexer) IPAddressLister { + return &iPAddressLister{indexer: indexer} +} + +// List lists all IPAddresses in the indexer. +func (s *iPAddressLister) List(selector labels.Selector) (ret []*v1alpha1.IPAddress, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.IPAddress)) + }) + return ret, err +} + +// Get retrieves the IPAddress from the index for a given name. +func (s *iPAddressLister) Get(name string) (*v1alpha1.IPAddress, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("ipaddress"), name) + } + return obj.(*v1alpha1.IPAddress), nil +} diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha1/podscheduling.go b/vendor/k8s.io/client-go/listers/resource/v1alpha1/podscheduling.go deleted file mode 100644 index fe43713710..0000000000 --- a/vendor/k8s.io/client-go/listers/resource/v1alpha1/podscheduling.go +++ /dev/null @@ -1,99 +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 v1alpha1 - -import ( - v1alpha1 "k8s.io/api/resource/v1alpha1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" -) - -// PodSchedulingLister helps list PodSchedulings. -// All objects returned here must be treated as read-only. -type PodSchedulingLister interface { - // List lists all PodSchedulings in the indexer. - // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.PodScheduling, err error) - // PodSchedulings returns an object that can list and get PodSchedulings. - PodSchedulings(namespace string) PodSchedulingNamespaceLister - PodSchedulingListerExpansion -} - -// podSchedulingLister implements the PodSchedulingLister interface. -type podSchedulingLister struct { - indexer cache.Indexer -} - -// NewPodSchedulingLister returns a new PodSchedulingLister. -func NewPodSchedulingLister(indexer cache.Indexer) PodSchedulingLister { - return &podSchedulingLister{indexer: indexer} -} - -// List lists all PodSchedulings in the indexer. -func (s *podSchedulingLister) List(selector labels.Selector) (ret []*v1alpha1.PodScheduling, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.PodScheduling)) - }) - return ret, err -} - -// PodSchedulings returns an object that can list and get PodSchedulings. -func (s *podSchedulingLister) PodSchedulings(namespace string) PodSchedulingNamespaceLister { - return podSchedulingNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// PodSchedulingNamespaceLister helps list and get PodSchedulings. -// All objects returned here must be treated as read-only. -type PodSchedulingNamespaceLister interface { - // List lists all PodSchedulings in the indexer for a given namespace. - // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.PodScheduling, err error) - // Get retrieves the PodScheduling from the indexer for a given namespace and name. - // Objects returned here must be treated as read-only. - Get(name string) (*v1alpha1.PodScheduling, error) - PodSchedulingNamespaceListerExpansion -} - -// podSchedulingNamespaceLister implements the PodSchedulingNamespaceLister -// interface. -type podSchedulingNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all PodSchedulings in the indexer for a given namespace. -func (s podSchedulingNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.PodScheduling, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.PodScheduling)) - }) - return ret, err -} - -// Get retrieves the PodScheduling from the indexer for a given namespace and name. -func (s podSchedulingNamespaceLister) Get(name string) (*v1alpha1.PodScheduling, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("podscheduling"), name) - } - return obj.(*v1alpha1.PodScheduling), nil -} diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go similarity index 79% rename from vendor/k8s.io/client-go/listers/resource/v1alpha1/expansion_generated.go rename to vendor/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go index 94885e784f..3b16e44290 100644 --- a/vendor/k8s.io/client-go/listers/resource/v1alpha1/expansion_generated.go +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go @@ -16,15 +16,15 @@ limitations under the License. // Code generated by lister-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 -// PodSchedulingListerExpansion allows custom methods to be added to -// PodSchedulingLister. -type PodSchedulingListerExpansion interface{} +// PodSchedulingContextListerExpansion allows custom methods to be added to +// PodSchedulingContextLister. +type PodSchedulingContextListerExpansion interface{} -// PodSchedulingNamespaceListerExpansion allows custom methods to be added to -// PodSchedulingNamespaceLister. -type PodSchedulingNamespaceListerExpansion interface{} +// PodSchedulingContextNamespaceListerExpansion allows custom methods to be added to +// PodSchedulingContextNamespaceLister. +type PodSchedulingContextNamespaceListerExpansion interface{} // ResourceClaimListerExpansion allows custom methods to be added to // ResourceClaimLister. diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha2/podschedulingcontext.go b/vendor/k8s.io/client-go/listers/resource/v1alpha2/podschedulingcontext.go new file mode 100644 index 0000000000..c50b3f8890 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha2/podschedulingcontext.go @@ -0,0 +1,99 @@ +/* +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 v1alpha2 + +import ( + v1alpha2 "k8s.io/api/resource/v1alpha2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PodSchedulingContextLister helps list PodSchedulingContexts. +// All objects returned here must be treated as read-only. +type PodSchedulingContextLister interface { + // List lists all PodSchedulingContexts in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.PodSchedulingContext, err error) + // PodSchedulingContexts returns an object that can list and get PodSchedulingContexts. + PodSchedulingContexts(namespace string) PodSchedulingContextNamespaceLister + PodSchedulingContextListerExpansion +} + +// podSchedulingContextLister implements the PodSchedulingContextLister interface. +type podSchedulingContextLister struct { + indexer cache.Indexer +} + +// NewPodSchedulingContextLister returns a new PodSchedulingContextLister. +func NewPodSchedulingContextLister(indexer cache.Indexer) PodSchedulingContextLister { + return &podSchedulingContextLister{indexer: indexer} +} + +// List lists all PodSchedulingContexts in the indexer. +func (s *podSchedulingContextLister) List(selector labels.Selector) (ret []*v1alpha2.PodSchedulingContext, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.PodSchedulingContext)) + }) + return ret, err +} + +// PodSchedulingContexts returns an object that can list and get PodSchedulingContexts. +func (s *podSchedulingContextLister) PodSchedulingContexts(namespace string) PodSchedulingContextNamespaceLister { + return podSchedulingContextNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// PodSchedulingContextNamespaceLister helps list and get PodSchedulingContexts. +// All objects returned here must be treated as read-only. +type PodSchedulingContextNamespaceLister interface { + // List lists all PodSchedulingContexts in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.PodSchedulingContext, err error) + // Get retrieves the PodSchedulingContext from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha2.PodSchedulingContext, error) + PodSchedulingContextNamespaceListerExpansion +} + +// podSchedulingContextNamespaceLister implements the PodSchedulingContextNamespaceLister +// interface. +type podSchedulingContextNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all PodSchedulingContexts in the indexer for a given namespace. +func (s podSchedulingContextNamespaceLister) List(selector labels.Selector) (ret []*v1alpha2.PodSchedulingContext, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.PodSchedulingContext)) + }) + return ret, err +} + +// Get retrieves the PodSchedulingContext from the indexer for a given namespace and name. +func (s podSchedulingContextNamespaceLister) Get(name string) (*v1alpha2.PodSchedulingContext, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha2.Resource("podschedulingcontext"), name) + } + return obj.(*v1alpha2.PodSchedulingContext), nil +} diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclaim.go b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaim.go similarity index 84% rename from vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclaim.go rename to vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaim.go index 05d5e0cfa4..273f16af31 100644 --- a/vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclaim.go +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaim.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by lister-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" @@ -30,7 +30,7 @@ import ( type ResourceClaimLister interface { // List lists all ResourceClaims in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.ResourceClaim, err error) + List(selector labels.Selector) (ret []*v1alpha2.ResourceClaim, err error) // ResourceClaims returns an object that can list and get ResourceClaims. ResourceClaims(namespace string) ResourceClaimNamespaceLister ResourceClaimListerExpansion @@ -47,9 +47,9 @@ func NewResourceClaimLister(indexer cache.Indexer) ResourceClaimLister { } // List lists all ResourceClaims in the indexer. -func (s *resourceClaimLister) List(selector labels.Selector) (ret []*v1alpha1.ResourceClaim, err error) { +func (s *resourceClaimLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClaim, err error) { err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.ResourceClaim)) + ret = append(ret, m.(*v1alpha2.ResourceClaim)) }) return ret, err } @@ -64,10 +64,10 @@ func (s *resourceClaimLister) ResourceClaims(namespace string) ResourceClaimName type ResourceClaimNamespaceLister interface { // List lists all ResourceClaims in the indexer for a given namespace. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.ResourceClaim, err error) + List(selector labels.Selector) (ret []*v1alpha2.ResourceClaim, err error) // Get retrieves the ResourceClaim from the indexer for a given namespace and name. // Objects returned here must be treated as read-only. - Get(name string) (*v1alpha1.ResourceClaim, error) + Get(name string) (*v1alpha2.ResourceClaim, error) ResourceClaimNamespaceListerExpansion } @@ -79,21 +79,21 @@ type resourceClaimNamespaceLister struct { } // List lists all ResourceClaims in the indexer for a given namespace. -func (s resourceClaimNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.ResourceClaim, err error) { +func (s resourceClaimNamespaceLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClaim, err error) { err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.ResourceClaim)) + ret = append(ret, m.(*v1alpha2.ResourceClaim)) }) return ret, err } // Get retrieves the ResourceClaim from the indexer for a given namespace and name. -func (s resourceClaimNamespaceLister) Get(name string) (*v1alpha1.ResourceClaim, error) { +func (s resourceClaimNamespaceLister) Get(name string) (*v1alpha2.ResourceClaim, error) { obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) if err != nil { return nil, err } if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("resourceclaim"), name) + return nil, errors.NewNotFound(v1alpha2.Resource("resourceclaim"), name) } - return obj.(*v1alpha1.ResourceClaim), nil + return obj.(*v1alpha2.ResourceClaim), nil } diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclaimtemplate.go b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaimtemplate.go similarity index 84% rename from vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclaimtemplate.go rename to vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaimtemplate.go index 97acddc7af..91a488b174 100644 --- a/vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclaimtemplate.go +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaimtemplate.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by lister-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" @@ -30,7 +30,7 @@ import ( type ResourceClaimTemplateLister interface { // List lists all ResourceClaimTemplates in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.ResourceClaimTemplate, err error) + List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimTemplate, err error) // ResourceClaimTemplates returns an object that can list and get ResourceClaimTemplates. ResourceClaimTemplates(namespace string) ResourceClaimTemplateNamespaceLister ResourceClaimTemplateListerExpansion @@ -47,9 +47,9 @@ func NewResourceClaimTemplateLister(indexer cache.Indexer) ResourceClaimTemplate } // List lists all ResourceClaimTemplates in the indexer. -func (s *resourceClaimTemplateLister) List(selector labels.Selector) (ret []*v1alpha1.ResourceClaimTemplate, err error) { +func (s *resourceClaimTemplateLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimTemplate, err error) { err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.ResourceClaimTemplate)) + ret = append(ret, m.(*v1alpha2.ResourceClaimTemplate)) }) return ret, err } @@ -64,10 +64,10 @@ func (s *resourceClaimTemplateLister) ResourceClaimTemplates(namespace string) R type ResourceClaimTemplateNamespaceLister interface { // List lists all ResourceClaimTemplates in the indexer for a given namespace. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.ResourceClaimTemplate, err error) + List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimTemplate, err error) // Get retrieves the ResourceClaimTemplate from the indexer for a given namespace and name. // Objects returned here must be treated as read-only. - Get(name string) (*v1alpha1.ResourceClaimTemplate, error) + Get(name string) (*v1alpha2.ResourceClaimTemplate, error) ResourceClaimTemplateNamespaceListerExpansion } @@ -79,21 +79,21 @@ type resourceClaimTemplateNamespaceLister struct { } // List lists all ResourceClaimTemplates in the indexer for a given namespace. -func (s resourceClaimTemplateNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.ResourceClaimTemplate, err error) { +func (s resourceClaimTemplateNamespaceLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimTemplate, err error) { err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.ResourceClaimTemplate)) + ret = append(ret, m.(*v1alpha2.ResourceClaimTemplate)) }) return ret, err } // Get retrieves the ResourceClaimTemplate from the indexer for a given namespace and name. -func (s resourceClaimTemplateNamespaceLister) Get(name string) (*v1alpha1.ResourceClaimTemplate, error) { +func (s resourceClaimTemplateNamespaceLister) Get(name string) (*v1alpha2.ResourceClaimTemplate, error) { obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) if err != nil { return nil, err } if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("resourceclaimtemplate"), name) + return nil, errors.NewNotFound(v1alpha2.Resource("resourceclaimtemplate"), name) } - return obj.(*v1alpha1.ResourceClaimTemplate), nil + return obj.(*v1alpha2.ResourceClaimTemplate), nil } diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclass.go b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclass.go similarity index 81% rename from vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclass.go rename to vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclass.go index 8d4dbf4d04..eeb2fc3379 100644 --- a/vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclass.go +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclass.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by lister-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" @@ -30,10 +30,10 @@ import ( type ResourceClassLister interface { // List lists all ResourceClasses in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.ResourceClass, err error) + List(selector labels.Selector) (ret []*v1alpha2.ResourceClass, err error) // Get retrieves the ResourceClass from the index for a given name. // Objects returned here must be treated as read-only. - Get(name string) (*v1alpha1.ResourceClass, error) + Get(name string) (*v1alpha2.ResourceClass, error) ResourceClassListerExpansion } @@ -48,21 +48,21 @@ func NewResourceClassLister(indexer cache.Indexer) ResourceClassLister { } // List lists all ResourceClasses in the indexer. -func (s *resourceClassLister) List(selector labels.Selector) (ret []*v1alpha1.ResourceClass, err error) { +func (s *resourceClassLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClass, err error) { err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.ResourceClass)) + ret = append(ret, m.(*v1alpha2.ResourceClass)) }) return ret, err } // Get retrieves the ResourceClass from the index for a given name. -func (s *resourceClassLister) Get(name string) (*v1alpha1.ResourceClass, error) { +func (s *resourceClassLister) Get(name string) (*v1alpha2.ResourceClass, error) { obj, exists, err := s.indexer.GetByKey(name) if err != nil { return nil, err } if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("resourceclass"), name) + return nil, errors.NewNotFound(v1alpha2.Resource("resourceclass"), name) } - return obj.(*v1alpha1.ResourceClass), nil + return obj.(*v1alpha2.ResourceClass), nil } diff --git a/vendor/k8s.io/client-go/openapi/OWNERS b/vendor/k8s.io/client-go/openapi/OWNERS new file mode 100644 index 0000000000..e610094242 --- /dev/null +++ b/vendor/k8s.io/client-go/openapi/OWNERS @@ -0,0 +1,4 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - apelisse diff --git a/vendor/k8s.io/client-go/pkg/version/base.go b/vendor/k8s.io/client-go/pkg/version/base.go index 51e34dda33..676d51d321 100644 --- a/vendor/k8s.io/client-go/pkg/version/base.go +++ b/vendor/k8s.io/client-go/pkg/version/base.go @@ -43,7 +43,8 @@ var ( gitMinor string = "" // minor version, numeric possibly followed by "+" // semantic version, derived by build scripts (see - // https://git.k8s.io/community/contributors/design-proposals/release/versioning.md + // https://github.com/kubernetes/sig-release/blob/master/release-engineering/versioning.md#kubernetes-release-versioning + // https://kubernetes.io/releases/version-skew-policy/ // for a detailed discussion of this field) // // TODO: This field is still called "gitVersion" for legacy diff --git a/vendor/k8s.io/client-go/rest/client.go b/vendor/k8s.io/client-go/rest/client.go index 2cf821bcd7..60df7e568c 100644 --- a/vendor/k8s.io/client-go/rest/client.go +++ b/vendor/k8s.io/client-go/rest/client.go @@ -52,8 +52,7 @@ type Interface interface { // ClientContentConfig controls how RESTClient communicates with the server. // // TODO: ContentConfig will be updated to accept a Negotiator instead of a -// -// NegotiatedSerializer and NegotiatedSerializer will be removed. +// NegotiatedSerializer and NegotiatedSerializer will be removed. type ClientContentConfig struct { // AcceptContentTypes specifies the types the client will accept and is optional. // If not set, ContentType will be used to define the Accept header diff --git a/vendor/k8s.io/client-go/rest/request.go b/vendor/k8s.io/client-go/rest/request.go index 560f73f002..bb6fb4decb 100644 --- a/vendor/k8s.io/client-go/rest/request.go +++ b/vendor/k8s.io/client-go/rest/request.go @@ -34,6 +34,7 @@ import ( "time" "golang.org/x/net/http2" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -116,8 +117,11 @@ type Request struct { subresource string // output - err error - body io.Reader + err error + + // only one of body / bodyBytes may be set. requests using body are not retriable. + body io.Reader + bodyBytes []byte retryFn requestRetryFunc } @@ -443,12 +447,15 @@ func (r *Request) Body(obj interface{}) *Request { return r } glogBody("Request Body", data) - r.body = bytes.NewReader(data) + r.body = nil + r.bodyBytes = data case []byte: glogBody("Request Body", t) - r.body = bytes.NewReader(t) + r.body = nil + r.bodyBytes = t case io.Reader: r.body = t + r.bodyBytes = nil case runtime.Object: // callers may pass typed interface pointers, therefore we must check nil with reflection if reflect.ValueOf(t).IsNil() { @@ -465,7 +472,8 @@ func (r *Request) Body(obj interface{}) *Request { return r } glogBody("Request Body", data) - r.body = bytes.NewReader(data) + r.body = nil + r.bodyBytes = data r.SetHeader("Content-Type", r.c.content.ContentType) default: r.err = fmt.Errorf("unknown type used for body: %+v", obj) @@ -473,7 +481,13 @@ func (r *Request) Body(obj interface{}) *Request { return r } -// URL returns the current working URL. +// Error returns any error encountered constructing the request, if any. +func (r *Request) Error() error { + return r.err +} + +// URL returns the current working URL. Check the result of Error() to ensure +// that the returned URL is valid. func (r *Request) URL() *url.URL { p := r.pathPrefix if r.namespaceSet && len(r.namespace) > 0 { @@ -718,7 +732,6 @@ func (r *Request) Watch(ctx context.Context) (watch.Interface, error) { } resp, err := client.Do(req) - updateURLMetrics(ctx, r, resp, err) retry.After(ctx, r, resp, err) if err == nil && resp.StatusCode == http.StatusOK { return r.newStreamWatcher(resp) @@ -778,22 +791,36 @@ func (r *Request) newStreamWatcher(resp *http.Response) (watch.Interface, error) ), nil } -// updateURLMetrics is a convenience function for pushing metrics. -// It also handles corner cases for incomplete/invalid request data. -func updateURLMetrics(ctx context.Context, req *Request, resp *http.Response, err error) { - url := "none" +// updateRequestResultMetric increments the RequestResult metric counter, +// it should be called with the (response, err) tuple from the final +// reply from the server. +func updateRequestResultMetric(ctx context.Context, req *Request, resp *http.Response, err error) { + code, host := sanitize(req, resp, err) + metrics.RequestResult.Increment(ctx, code, req.verb, host) +} + +// updateRequestRetryMetric increments the RequestRetry metric counter, +// it should be called with the (response, err) tuple for each retry +// except for the final attempt. +func updateRequestRetryMetric(ctx context.Context, req *Request, resp *http.Response, err error) { + code, host := sanitize(req, resp, err) + metrics.RequestRetry.IncrementRetry(ctx, code, req.verb, host) +} + +func sanitize(req *Request, resp *http.Response, err error) (string, string) { + host := "none" if req.c.base != nil { - url = req.c.base.Host + host = req.c.base.Host } // Errors can be arbitrary strings. Unbound label cardinality is not suitable for a metric // system so we just report them as ``. - if err != nil { - metrics.RequestResult.Increment(ctx, "", req.verb, url) - } else { - // Metrics for failure codes - metrics.RequestResult.Increment(ctx, strconv.Itoa(resp.StatusCode), req.verb, url) + code := "" + if resp != nil { + code = strconv.Itoa(resp.StatusCode) } + + return code, host } // Stream formats and executes the request, and offers streaming of the response. @@ -825,11 +852,7 @@ func (r *Request) Stream(ctx context.Context) (io.ReadCloser, error) { if err != nil { return nil, err } - if r.body != nil { - req.Body = io.NopCloser(r.body) - } resp, err := client.Do(req) - updateURLMetrics(ctx, r, resp, err) retry.After(ctx, r, resp, err) if err != nil { // we only retry on an HTTP response with 'Retry-After' header @@ -889,8 +912,20 @@ func (r *Request) requestPreflightCheck() error { } func (r *Request) newHTTPRequest(ctx context.Context) (*http.Request, error) { + var body io.Reader + switch { + case r.body != nil && r.bodyBytes != nil: + return nil, fmt.Errorf("cannot set both body and bodyBytes") + case r.body != nil: + body = r.body + case r.bodyBytes != nil: + // Create a new reader specifically for this request. + // Giving each request a dedicated reader allows retries to avoid races resetting the request body. + body = bytes.NewReader(r.bodyBytes) + } + url := r.URL().String() - req, err := http.NewRequest(r.verb, url, r.body) + req, err := http.NewRequest(r.verb, url, body) if err != nil { return nil, err } @@ -962,7 +997,6 @@ func (r *Request) request(ctx context.Context, fn func(*http.Request, *http.Resp return err } resp, err := client.Do(req) - updateURLMetrics(ctx, r, resp, err) // The value -1 or a value of 0 with a non-nil Body indicates that the length is unknown. // https://pkg.go.dev/net/http#Request if req.ContentLength >= 0 && !(req.Body != nil && req.ContentLength == 0) { diff --git a/vendor/k8s.io/client-go/rest/with_retry.go b/vendor/k8s.io/client-go/rest/with_retry.go index b04e3e9eff..eaaadc6a4c 100644 --- a/vendor/k8s.io/client-go/rest/with_retry.go +++ b/vendor/k8s.io/client-go/rest/with_retry.go @@ -153,6 +153,11 @@ func (r *withRetry) IsNextRetry(ctx context.Context, restReq *Request, httpReq * return false } + if restReq.body != nil { + // we have an opaque reader, we can't safely reset it + return false + } + r.attempts++ r.retryAfter = &RetryAfter{Attempt: r.attempts} if r.attempts > r.maxRetries { @@ -209,18 +214,6 @@ func (r *withRetry) Before(ctx context.Context, request *Request) error { return nil } - // At this point we've made atleast one attempt, post which the response - // body should have been fully read and closed in order for it to be safe - // to reset the request body before we reconnect, in order for us to reuse - // the same TCP connection. - if seeker, ok := request.body.(io.Seeker); ok && request.body != nil { - if _, err := seeker.Seek(0, io.SeekStart); err != nil { - err = fmt.Errorf("failed to reset the request body while retrying a request: %v", err) - r.trackPreviousError(err) - return err - } - } - // if we are here, we have made attempt(s) at least once before. if request.backoff != nil { delay := request.backoff.CalculateBackoff(url) @@ -249,8 +242,20 @@ func (r *withRetry) After(ctx context.Context, request *Request, resp *http.Resp // parameters calculated from the (response, err) tuple from // attempt N-1, so r.retryAfter is outdated and should not be // referred to here. + isRetry := r.retryAfter != nil r.retryAfter = nil + // the client finishes a single request after N attempts (1..N) + // - all attempts (1..N) are counted to the rest_client_requests_total + // metric (current behavior). + // - every attempt after the first (2..N) are counted to the + // rest_client_request_retries_total metric. + updateRequestResultMetric(ctx, request, resp, err) + if isRetry { + // this is attempt 2 or later + updateRequestRetryMetric(ctx, request, resp, err) + } + if request.c.base != nil { if err != nil { request.backoff.UpdateBackoff(request.URL(), err, 0) @@ -353,8 +358,12 @@ func retryAfterResponse() *http.Response { } func retryAfterResponseWithDelay(delay string) *http.Response { + return retryAfterResponseWithCodeAndDelay(http.StatusInternalServerError, delay) +} + +func retryAfterResponseWithCodeAndDelay(code int, delay string) *http.Response { return &http.Response{ - StatusCode: http.StatusInternalServerError, + StatusCode: code, Header: http.Header{"Retry-After": []string{delay}}, } } diff --git a/vendor/k8s.io/client-go/tools/cache/controller.go b/vendor/k8s.io/client-go/tools/cache/controller.go index 0762da3bef..f437f28616 100644 --- a/vendor/k8s.io/client-go/tools/cache/controller.go +++ b/vendor/k8s.io/client-go/tools/cache/controller.go @@ -18,6 +18,7 @@ package cache import ( "errors" + "os" "sync" "time" @@ -50,11 +51,12 @@ type Config struct { Process ProcessFunc // ObjectType is an example object of the type this controller is - // expected to handle. Only the type needs to be right, except - // that when that is `unstructured.Unstructured` the object's - // `"apiVersion"` and `"kind"` must also be right. + // expected to handle. ObjectType runtime.Object + // ObjectDescription is the description to use when logging type-specific information about this controller. + ObjectDescription string + // FullResyncPeriod is the period at which ShouldResync is considered. FullResyncPeriod time.Duration @@ -84,7 +86,7 @@ type Config struct { type ShouldResyncFunc func() bool // ProcessFunc processes a single object. -type ProcessFunc func(obj interface{}) error +type ProcessFunc func(obj interface{}, isInInitialList bool) error // `*controller` implements Controller type controller struct { @@ -131,18 +133,24 @@ func (c *controller) Run(stopCh <-chan struct{}) { <-stopCh c.config.Queue.Close() }() - r := NewReflector( + r := NewReflectorWithOptions( c.config.ListerWatcher, c.config.ObjectType, c.config.Queue, - c.config.FullResyncPeriod, + ReflectorOptions{ + ResyncPeriod: c.config.FullResyncPeriod, + TypeDescription: c.config.ObjectDescription, + Clock: c.clock, + }, ) r.ShouldResync = c.config.ShouldResync r.WatchListPageSize = c.config.WatchListPageSize - r.clock = c.clock if c.config.WatchErrorHandler != nil { r.watchErrorHandler = c.config.WatchErrorHandler } + if s := os.Getenv("ENABLE_CLIENT_GO_WATCH_LIST_ALPHA"); len(s) > 0 { + r.UseWatchList = true + } c.reflectorMutex.Lock() c.reflector = r @@ -211,7 +219,7 @@ func (c *controller) processLoop() { // happen if the watch is closed and misses the delete event and we don't // notice the deletion until the subsequent re-list. type ResourceEventHandler interface { - OnAdd(obj interface{}) + OnAdd(obj interface{}, isInInitialList bool) OnUpdate(oldObj, newObj interface{}) OnDelete(obj interface{}) } @@ -220,6 +228,9 @@ type ResourceEventHandler interface { // as few of the notification functions as you want while still implementing // ResourceEventHandler. This adapter does not remove the prohibition against // modifying the objects. +// +// See ResourceEventHandlerDetailedFuncs if your use needs to propagate +// HasSynced. type ResourceEventHandlerFuncs struct { AddFunc func(obj interface{}) UpdateFunc func(oldObj, newObj interface{}) @@ -227,7 +238,7 @@ type ResourceEventHandlerFuncs struct { } // OnAdd calls AddFunc if it's not nil. -func (r ResourceEventHandlerFuncs) OnAdd(obj interface{}) { +func (r ResourceEventHandlerFuncs) OnAdd(obj interface{}, isInInitialList bool) { if r.AddFunc != nil { r.AddFunc(obj) } @@ -247,6 +258,36 @@ func (r ResourceEventHandlerFuncs) OnDelete(obj interface{}) { } } +// ResourceEventHandlerDetailedFuncs is exactly like ResourceEventHandlerFuncs +// except its AddFunc accepts the isInInitialList parameter, for propagating +// HasSynced. +type ResourceEventHandlerDetailedFuncs struct { + AddFunc func(obj interface{}, isInInitialList bool) + UpdateFunc func(oldObj, newObj interface{}) + DeleteFunc func(obj interface{}) +} + +// OnAdd calls AddFunc if it's not nil. +func (r ResourceEventHandlerDetailedFuncs) OnAdd(obj interface{}, isInInitialList bool) { + if r.AddFunc != nil { + r.AddFunc(obj, isInInitialList) + } +} + +// OnUpdate calls UpdateFunc if it's not nil. +func (r ResourceEventHandlerDetailedFuncs) OnUpdate(oldObj, newObj interface{}) { + if r.UpdateFunc != nil { + r.UpdateFunc(oldObj, newObj) + } +} + +// OnDelete calls DeleteFunc if it's not nil. +func (r ResourceEventHandlerDetailedFuncs) OnDelete(obj interface{}) { + if r.DeleteFunc != nil { + r.DeleteFunc(obj) + } +} + // FilteringResourceEventHandler applies the provided filter to all events coming // in, ensuring the appropriate nested handler method is invoked. An object // that starts passing the filter after an update is considered an add, and an @@ -258,11 +299,11 @@ type FilteringResourceEventHandler struct { } // OnAdd calls the nested handler only if the filter succeeds -func (r FilteringResourceEventHandler) OnAdd(obj interface{}) { +func (r FilteringResourceEventHandler) OnAdd(obj interface{}, isInInitialList bool) { if !r.FilterFunc(obj) { return } - r.Handler.OnAdd(obj) + r.Handler.OnAdd(obj, isInInitialList) } // OnUpdate ensures the proper handler is called depending on whether the filter matches @@ -273,7 +314,7 @@ func (r FilteringResourceEventHandler) OnUpdate(oldObj, newObj interface{}) { case newer && older: r.Handler.OnUpdate(oldObj, newObj) case newer && !older: - r.Handler.OnAdd(newObj) + r.Handler.OnAdd(newObj, false) case !newer && older: r.Handler.OnDelete(oldObj) default: @@ -353,17 +394,6 @@ func NewIndexerInformer( return clientState, newInformer(lw, objType, resyncPeriod, h, clientState, nil) } -// TransformFunc allows for transforming an object before it will be processed -// and put into the controller cache and before the corresponding handlers will -// be called on it. -// TransformFunc (similarly to ResourceEventHandler functions) should be able -// to correctly handle the tombstone of type cache.DeletedFinalStateUnknown -// -// The most common usage pattern is to clean-up some parts of the object to -// reduce component memory usage if a given component doesn't care about them. -// given controller doesn't care for them -type TransformFunc func(interface{}) (interface{}, error) - // NewTransformingInformer returns a Store and a controller for populating // the store while also providing event notifications. You should only used // the returned Store for Get/List operations; Add/Modify/Deletes will cause @@ -411,19 +441,12 @@ func processDeltas( // Object which receives event notifications from the given deltas handler ResourceEventHandler, clientState Store, - transformer TransformFunc, deltas Deltas, + isInInitialList bool, ) error { // from oldest to newest for _, d := range deltas { obj := d.Object - if transformer != nil { - var err error - obj, err = transformer(obj) - if err != nil { - return err - } - } switch d.Type { case Sync, Replaced, Added, Updated: @@ -436,7 +459,7 @@ func processDeltas( if err := clientState.Add(obj); err != nil { return err } - handler.OnAdd(obj) + handler.OnAdd(obj, isInInitialList) } case Deleted: if err := clientState.Delete(obj); err != nil { @@ -475,6 +498,7 @@ func newInformer( fifo := NewDeltaFIFOWithOptions(DeltaFIFOOptions{ KnownObjects: clientState, EmitDeltaTypeReplaced: true, + Transformer: transformer, }) cfg := &Config{ @@ -484,9 +508,9 @@ func newInformer( FullResyncPeriod: resyncPeriod, RetryOnError: false, - Process: func(obj interface{}) error { + Process: func(obj interface{}, isInInitialList bool) error { if deltas, ok := obj.(Deltas); ok { - return processDeltas(h, clientState, transformer, deltas) + return processDeltas(h, clientState, deltas, isInInitialList) } return errors.New("object given as Process argument is not Deltas") }, diff --git a/vendor/k8s.io/client-go/tools/cache/delta_fifo.go b/vendor/k8s.io/client-go/tools/cache/delta_fifo.go index 0c13a41f06..7160bb1ee7 100644 --- a/vendor/k8s.io/client-go/tools/cache/delta_fifo.go +++ b/vendor/k8s.io/client-go/tools/cache/delta_fifo.go @@ -51,6 +51,10 @@ type DeltaFIFOOptions struct { // When true, `Replaced` events will be sent for items passed to a Replace() call. // When false, `Sync` events will be sent instead. EmitDeltaTypeReplaced bool + + // If set, will be called for objects before enqueueing them. Please + // see the comment on TransformFunc for details. + Transformer TransformFunc } // DeltaFIFO is like FIFO, but differs in two ways. One is that the @@ -129,8 +133,32 @@ type DeltaFIFO struct { // emitDeltaTypeReplaced is whether to emit the Replaced or Sync // DeltaType when Replace() is called (to preserve backwards compat). emitDeltaTypeReplaced bool + + // Called with every object if non-nil. + transformer TransformFunc } +// TransformFunc allows for transforming an object before it will be processed. +// TransformFunc (similarly to ResourceEventHandler functions) should be able +// to correctly handle the tombstone of type cache.DeletedFinalStateUnknown. +// +// New in v1.27: In such cases, the contained object will already have gone +// through the transform object separately (when it was added / updated prior +// to the delete), so the TransformFunc can likely safely ignore such objects +// (i.e., just return the input object). +// +// The most common usage pattern is to clean-up some parts of the object to +// reduce component memory usage if a given component doesn't care about them. +// +// New in v1.27: unless the object is a DeletedFinalStateUnknown, TransformFunc +// sees the object before any other actor, and it is now safe to mutate the +// object in place instead of making a copy. +// +// Note that TransformFunc is called while inserting objects into the +// notification queue and is therefore extremely performance sensitive; please +// do not do anything that will take a long time. +type TransformFunc func(interface{}) (interface{}, error) + // DeltaType is the type of a change (addition, deletion, etc) type DeltaType string @@ -227,6 +255,7 @@ func NewDeltaFIFOWithOptions(opts DeltaFIFOOptions) *DeltaFIFO { knownObjects: opts.KnownObjects, emitDeltaTypeReplaced: opts.EmitDeltaTypeReplaced, + transformer: opts.Transformer, } f.cond.L = &f.lock return f @@ -271,6 +300,10 @@ func (f *DeltaFIFO) KeyOf(obj interface{}) (string, error) { func (f *DeltaFIFO) HasSynced() bool { f.lock.Lock() defer f.lock.Unlock() + return f.hasSynced_locked() +} + +func (f *DeltaFIFO) hasSynced_locked() bool { return f.populated && f.initialPopulationCount == 0 } @@ -411,6 +444,21 @@ func (f *DeltaFIFO) queueActionLocked(actionType DeltaType, obj interface{}) err if err != nil { return KeyError{obj, err} } + + // Every object comes through this code path once, so this is a good + // place to call the transform func. If obj is a + // DeletedFinalStateUnknown tombstone, then the containted inner object + // will already have gone through the transformer, but we document that + // this can happen. In cases involving Replace(), such an object can + // come through multiple times. + if f.transformer != nil { + var err error + obj, err = f.transformer(obj) + if err != nil { + return err + } + } + oldDeltas := f.items[id] newDeltas := append(oldDeltas, Delta{actionType, obj}) newDeltas = dedupDeltas(newDeltas) @@ -526,6 +574,7 @@ func (f *DeltaFIFO) Pop(process PopProcessFunc) (interface{}, error) { f.cond.Wait() } + isInInitialList := !f.hasSynced_locked() id := f.queue[0] f.queue = f.queue[1:] depth := len(f.queue) @@ -551,7 +600,7 @@ func (f *DeltaFIFO) Pop(process PopProcessFunc) (interface{}, error) { utiltrace.Field{Key: "Reason", Value: "slow event handlers blocking the queue"}) defer trace.LogIfLong(100 * time.Millisecond) } - err := process(item) + err := process(item, isInInitialList) if e, ok := err.(ErrRequeue); ok { f.addIfNotPresent(id, item) err = e.Err @@ -566,12 +615,11 @@ func (f *DeltaFIFO) Pop(process PopProcessFunc) (interface{}, error) { // using the Sync or Replace DeltaType and then (2) it does some deletions. // In particular: for every pre-existing key K that is not the key of // an object in `list` there is the effect of -// `Delete(DeletedFinalStateUnknown{K, O})` where O is current object -// of K. If `f.knownObjects == nil` then the pre-existing keys are -// those in `f.items` and the current object of K is the `.Newest()` -// of the Deltas associated with K. Otherwise the pre-existing keys -// are those listed by `f.knownObjects` and the current object of K is -// what `f.knownObjects.GetByKey(K)` returns. +// `Delete(DeletedFinalStateUnknown{K, O})` where O is the latest known +// object of K. The pre-existing keys are those in the union set of the keys in +// `f.items` and `f.knownObjects` (if not nil). The last known object for key K is +// the one present in the last delta in `f.items`. If there is no delta for K +// in `f.items`, it is the object in `f.knownObjects` func (f *DeltaFIFO) Replace(list []interface{}, _ string) error { f.lock.Lock() defer f.lock.Unlock() @@ -595,51 +643,23 @@ func (f *DeltaFIFO) Replace(list []interface{}, _ string) error { } } - if f.knownObjects == nil { - // Do deletion detection against our own list. - queuedDeletions := 0 - for k, oldItem := range f.items { - if keys.Has(k) { - continue - } - // Delete pre-existing items not in the new list. - // This could happen if watch deletion event was missed while - // disconnected from apiserver. - var deletedObj interface{} - if n := oldItem.Newest(); n != nil { - deletedObj = n.Object - } - queuedDeletions++ - if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil { - return err - } - } - - if !f.populated { - f.populated = true - // While there shouldn't be any queued deletions in the initial - // population of the queue, it's better to be on the safe side. - f.initialPopulationCount = keys.Len() + queuedDeletions - } - - return nil - } - - // Detect deletions not already in the queue. - knownKeys := f.knownObjects.ListKeys() + // Do deletion detection against objects in the queue queuedDeletions := 0 - for _, k := range knownKeys { + for k, oldItem := range f.items { if keys.Has(k) { continue } - - deletedObj, exists, err := f.knownObjects.GetByKey(k) - if err != nil { - deletedObj = nil - klog.Errorf("Unexpected error %v during lookup of key %v, placing DeleteFinalStateUnknown marker without object", err, k) - } else if !exists { - deletedObj = nil - klog.Infof("Key %v does not exist in known objects store, placing DeleteFinalStateUnknown marker without object", k) + // Delete pre-existing items not in the new list. + // This could happen if watch deletion event was missed while + // disconnected from apiserver. + var deletedObj interface{} + if n := oldItem.Newest(); n != nil { + deletedObj = n.Object + + // if the previous object is a DeletedFinalStateUnknown, we have to extract the actual Object + if d, ok := deletedObj.(DeletedFinalStateUnknown); ok { + deletedObj = d.Obj + } } queuedDeletions++ if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil { @@ -647,6 +667,32 @@ func (f *DeltaFIFO) Replace(list []interface{}, _ string) error { } } + if f.knownObjects != nil { + // Detect deletions for objects not present in the queue, but present in KnownObjects + knownKeys := f.knownObjects.ListKeys() + for _, k := range knownKeys { + if keys.Has(k) { + continue + } + if len(f.items[k]) > 0 { + continue + } + + deletedObj, exists, err := f.knownObjects.GetByKey(k) + if err != nil { + deletedObj = nil + klog.Errorf("Unexpected error %v during lookup of key %v, placing DeleteFinalStateUnknown marker without object", err, k) + } else if !exists { + deletedObj = nil + klog.Infof("Key %v does not exist in known objects store, placing DeleteFinalStateUnknown marker without object", k) + } + queuedDeletions++ + if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil { + return err + } + } + } + if !f.populated { f.populated = true f.initialPopulationCount = keys.Len() + queuedDeletions diff --git a/vendor/k8s.io/client-go/tools/cache/fifo.go b/vendor/k8s.io/client-go/tools/cache/fifo.go index 8f3313783d..dd13c4ea77 100644 --- a/vendor/k8s.io/client-go/tools/cache/fifo.go +++ b/vendor/k8s.io/client-go/tools/cache/fifo.go @@ -25,7 +25,7 @@ import ( // PopProcessFunc is passed to Pop() method of Queue interface. // It is supposed to process the accumulator popped from the queue. -type PopProcessFunc func(interface{}) error +type PopProcessFunc func(obj interface{}, isInInitialList bool) error // ErrRequeue may be returned by a PopProcessFunc to safely requeue // the current item. The value of Err will be returned from Pop. @@ -82,9 +82,12 @@ type Queue interface { // Pop is helper function for popping from Queue. // WARNING: Do NOT use this function in non-test code to avoid races // unless you really really really really know what you are doing. +// +// NOTE: This function is deprecated and may be removed in the future without +// additional warning. func Pop(queue Queue) interface{} { var result interface{} - queue.Pop(func(obj interface{}) error { + queue.Pop(func(obj interface{}, isInInitialList bool) error { result = obj return nil }) @@ -149,6 +152,10 @@ func (f *FIFO) Close() { func (f *FIFO) HasSynced() bool { f.lock.Lock() defer f.lock.Unlock() + return f.hasSynced_locked() +} + +func (f *FIFO) hasSynced_locked() bool { return f.populated && f.initialPopulationCount == 0 } @@ -287,6 +294,7 @@ func (f *FIFO) Pop(process PopProcessFunc) (interface{}, error) { f.cond.Wait() } + isInInitialList := !f.hasSynced_locked() id := f.queue[0] f.queue = f.queue[1:] if f.initialPopulationCount > 0 { @@ -298,7 +306,7 @@ func (f *FIFO) Pop(process PopProcessFunc) (interface{}, error) { continue } delete(f.items, id) - err := process(item) + err := process(item, isInInitialList) if e, ok := err.(ErrRequeue); ok { f.addIfNotPresent(id, item) err = e.Err diff --git a/vendor/k8s.io/client-go/tools/cache/reflector.go b/vendor/k8s.io/client-go/tools/cache/reflector.go index 9cd476be8a..2b335c104c 100644 --- a/vendor/k8s.io/client-go/tools/cache/reflector.go +++ b/vendor/k8s.io/client-go/tools/cache/reflector.go @@ -23,6 +23,7 @@ import ( "io" "math/rand" "reflect" + "strings" "sync" "time" @@ -40,6 +41,7 @@ import ( "k8s.io/client-go/tools/pager" "k8s.io/klog/v2" "k8s.io/utils/clock" + "k8s.io/utils/pointer" "k8s.io/utils/trace" ) @@ -49,12 +51,11 @@ const defaultExpectedTypeName = "" type Reflector struct { // name identifies this reflector. By default it will be a file:line if possible. name string - // The name of the type we expect to place in the store. The name // will be the stringification of expectedGVK if provided, and the // stringification of expectedType otherwise. It is for display // only, and should not be used for parsing or comparison. - expectedTypeName string + typeDescription string // An example object of the type we expect to place in the store. // Only the type needs to be right, except that when that is // `unstructured.Unstructured` the object's `"apiVersion"` and @@ -66,17 +67,11 @@ type Reflector struct { store Store // listerWatcher is used to perform lists and watches. listerWatcher ListerWatcher - // backoff manages backoff of ListWatch backoffManager wait.BackoffManager // initConnBackoffManager manages backoff the initial connection with the Watch call of ListAndWatch. initConnBackoffManager wait.BackoffManager - // MaxInternalErrorRetryDuration defines how long we should retry internal errors returned by watch. - MaxInternalErrorRetryDuration time.Duration - - resyncPeriod time.Duration - // ShouldResync is invoked periodically and whenever it returns `true` the Store's Resync operation is invoked - ShouldResync func() bool + resyncPeriod time.Duration // clock allows tests to manipulate time clock clock.Clock // paginatedResult defines whether pagination should be forced for list calls. @@ -91,6 +86,8 @@ type Reflector struct { isLastSyncResourceVersionUnavailable bool // lastSyncResourceVersionMutex guards read/write access to lastSyncResourceVersion lastSyncResourceVersionMutex sync.RWMutex + // Called whenever the ListAndWatch drops the connection with an error. + watchErrorHandler WatchErrorHandler // WatchListPageSize is the requested chunk size of initial and resync watch lists. // If unset, for consistent reads (RV="") or reads that opt-into arbitrarily old data // (RV="0") it will default to pager.PageSize, for the rest (RV != "" && RV != "0") @@ -99,8 +96,19 @@ type Reflector struct { // etcd, which is significantly less efficient and may lead to serious performance and // scalability problems. WatchListPageSize int64 - // Called whenever the ListAndWatch drops the connection with an error. - watchErrorHandler WatchErrorHandler + // ShouldResync is invoked periodically and whenever it returns `true` the Store's Resync operation is invoked + ShouldResync func() bool + // MaxInternalErrorRetryDuration defines how long we should retry internal errors returned by watch. + MaxInternalErrorRetryDuration time.Duration + // UseWatchList if turned on instructs the reflector to open a stream to bring data from the API server. + // Streaming has the primary advantage of using fewer server's resources to fetch data. + // + // The old behaviour establishes a LIST request which gets data in chunks. + // Paginated list is less efficient and depending on the actual size of objects + // might result in an increased memory consumption of the APIServer. + // + // See https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/3157-watch-list#design-details + UseWatchList bool } // ResourceVersionUpdater is an interface that allows store implementation to @@ -131,13 +139,13 @@ func DefaultWatchErrorHandler(r *Reflector, err error) { // Don't set LastSyncResourceVersionUnavailable - LIST call with ResourceVersion=RV already // has a semantic that it returns data at least as fresh as provided RV. // So first try to LIST with setting RV to resource version of last observed object. - klog.V(4).Infof("%s: watch of %v closed with: %v", r.name, r.expectedTypeName, err) + klog.V(4).Infof("%s: watch of %v closed with: %v", r.name, r.typeDescription, err) case err == io.EOF: // watch closed normally case err == io.ErrUnexpectedEOF: - klog.V(1).Infof("%s: Watch for %v closed with unexpected EOF: %v", r.name, r.expectedTypeName, err) + klog.V(1).Infof("%s: Watch for %v closed with unexpected EOF: %v", r.name, r.typeDescription, err) default: - utilruntime.HandleError(fmt.Errorf("%s: Failed to watch %v: %v", r.name, r.expectedTypeName, err)) + utilruntime.HandleError(fmt.Errorf("%s: Failed to watch %v: %v", r.name, r.typeDescription, err)) } } @@ -155,7 +163,40 @@ func NewNamespaceKeyedIndexerAndReflector(lw ListerWatcher, expectedType interfa return indexer, reflector } -// NewReflector creates a new Reflector object which will keep the +// NewReflector creates a new Reflector with its name defaulted to the closest source_file.go:line in the call stack +// that is outside this package. See NewReflectorWithOptions for further information. +func NewReflector(lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector { + return NewReflectorWithOptions(lw, expectedType, store, ReflectorOptions{ResyncPeriod: resyncPeriod}) +} + +// NewNamedReflector creates a new Reflector with the specified name. See NewReflectorWithOptions for further +// information. +func NewNamedReflector(name string, lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector { + return NewReflectorWithOptions(lw, expectedType, store, ReflectorOptions{Name: name, ResyncPeriod: resyncPeriod}) +} + +// ReflectorOptions configures a Reflector. +type ReflectorOptions struct { + // Name is the Reflector's name. If unset/unspecified, the name defaults to the closest source_file.go:line + // in the call stack that is outside this package. + Name string + + // TypeDescription is the Reflector's type description. If unset/unspecified, the type description is defaulted + // using the following rules: if the expectedType passed to NewReflectorWithOptions was nil, the type description is + // "". If the expectedType is an instance of *unstructured.Unstructured and its apiVersion and kind fields + // are set, the type description is the string encoding of those. Otherwise, the type description is set to the + // go type of expectedType.. + TypeDescription string + + // ResyncPeriod is the Reflector's resync period. If unset/unspecified, the resync period defaults to 0 + // (do not resync). + ResyncPeriod time.Duration + + // Clock allows tests to control time. If unset defaults to clock.RealClock{} + Clock clock.Clock +} + +// NewReflectorWithOptions creates a new Reflector object which will keep the // given store up to date with the server's contents for the given // resource. Reflector promises to only put things in the store that // have the type of expectedType, unless expectedType is nil. If @@ -165,49 +206,74 @@ func NewNamespaceKeyedIndexerAndReflector(lw ListerWatcher, expectedType interfa // "yes". This enables you to use reflectors to periodically process // everything as well as incrementally processing the things that // change. -func NewReflector(lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector { - return NewNamedReflector(naming.GetNameFromCallsite(internalPackages...), lw, expectedType, store, resyncPeriod) -} - -// NewNamedReflector same as NewReflector, but with a specified name for logging -func NewNamedReflector(name string, lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector { - realClock := &clock.RealClock{} +func NewReflectorWithOptions(lw ListerWatcher, expectedType interface{}, store Store, options ReflectorOptions) *Reflector { + reflectorClock := options.Clock + if reflectorClock == nil { + reflectorClock = clock.RealClock{} + } r := &Reflector{ - name: name, - listerWatcher: lw, - store: store, + name: options.Name, + resyncPeriod: options.ResyncPeriod, + typeDescription: options.TypeDescription, + listerWatcher: lw, + store: store, // We used to make the call every 1sec (1 QPS), the goal here is to achieve ~98% traffic reduction when // API server is not healthy. With these parameters, backoff will stop at [30,60) sec interval which is // 0.22 QPS. If we don't backoff for 2min, assume API server is healthy and we reset the backoff. - backoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, realClock), - initConnBackoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, realClock), - resyncPeriod: resyncPeriod, - clock: realClock, + backoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, reflectorClock), + initConnBackoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, reflectorClock), + clock: reflectorClock, watchErrorHandler: WatchErrorHandler(DefaultWatchErrorHandler), + expectedType: reflect.TypeOf(expectedType), } - r.setExpectedType(expectedType) + + if r.name == "" { + r.name = naming.GetNameFromCallsite(internalPackages...) + } + + if r.typeDescription == "" { + r.typeDescription = getTypeDescriptionFromObject(expectedType) + } + + if r.expectedGVK == nil { + r.expectedGVK = getExpectedGVKFromObject(expectedType) + } + return r } -func (r *Reflector) setExpectedType(expectedType interface{}) { - r.expectedType = reflect.TypeOf(expectedType) - if r.expectedType == nil { - r.expectedTypeName = defaultExpectedTypeName - return +func getTypeDescriptionFromObject(expectedType interface{}) string { + if expectedType == nil { + return defaultExpectedTypeName } - r.expectedTypeName = r.expectedType.String() + reflectDescription := reflect.TypeOf(expectedType).String() - if obj, ok := expectedType.(*unstructured.Unstructured); ok { - // Use gvk to check that watch event objects are of the desired type. - gvk := obj.GroupVersionKind() - if gvk.Empty() { - klog.V(4).Infof("Reflector from %s configured with expectedType of *unstructured.Unstructured with empty GroupVersionKind.", r.name) - return - } - r.expectedGVK = &gvk - r.expectedTypeName = gvk.String() + obj, ok := expectedType.(*unstructured.Unstructured) + if !ok { + return reflectDescription } + + gvk := obj.GroupVersionKind() + if gvk.Empty() { + return reflectDescription + } + + return gvk.String() +} + +func getExpectedGVKFromObject(expectedType interface{}) *schema.GroupVersionKind { + obj, ok := expectedType.(*unstructured.Unstructured) + if !ok { + return nil + } + + gvk := obj.GroupVersionKind() + if gvk.Empty() { + return nil + } + + return &gvk } // internalPackages are packages that ignored when creating a default reflector name. These packages are in the common @@ -218,13 +284,13 @@ var internalPackages = []string{"client-go/tools/cache/"} // objects and subsequent deltas. // Run will exit when stopCh is closed. func (r *Reflector) Run(stopCh <-chan struct{}) { - klog.V(3).Infof("Starting reflector %s (%s) from %s", r.expectedTypeName, r.resyncPeriod, r.name) + klog.V(3).Infof("Starting reflector %s (%s) from %s", r.typeDescription, r.resyncPeriod, r.name) wait.BackoffUntil(func() { if err := r.ListAndWatch(stopCh); err != nil { r.watchErrorHandler(r, err) } }, r.backoffManager, true, stopCh) - klog.V(3).Infof("Stopping reflector %s (%s) from %s", r.expectedTypeName, r.resyncPeriod, r.name) + klog.V(3).Infof("Stopping reflector %s (%s) from %s", r.typeDescription, r.resyncPeriod, r.name) } var ( @@ -254,42 +320,75 @@ func (r *Reflector) resyncChan() (<-chan time.Time, func() bool) { // and then use the resource version to watch. // It returns error if ListAndWatch didn't even try to initialize watch. func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error { - klog.V(3).Infof("Listing and watching %v from %s", r.expectedTypeName, r.name) + klog.V(3).Infof("Listing and watching %v from %s", r.typeDescription, r.name) + var err error + var w watch.Interface + fallbackToList := !r.UseWatchList - err := r.list(stopCh) - if err != nil { - return err + if r.UseWatchList { + w, err = r.watchList(stopCh) + if w == nil && err == nil { + // stopCh was closed + return nil + } + if err != nil { + if !apierrors.IsInvalid(err) { + return err + } + klog.Warning("the watch-list feature is not supported by the server, falling back to the previous LIST/WATCH semantic") + fallbackToList = true + // Ensure that we won't accidentally pass some garbage down the watch. + w = nil + } + } + + if fallbackToList { + err = r.list(stopCh) + if err != nil { + return err + } } resyncerrc := make(chan error, 1) cancelCh := make(chan struct{}) defer close(cancelCh) - go func() { - resyncCh, cleanup := r.resyncChan() - defer func() { - cleanup() // Call the last one written into cleanup - }() - for { - select { - case <-resyncCh: - case <-stopCh: - return - case <-cancelCh: + go r.startResync(stopCh, cancelCh, resyncerrc) + return r.watch(w, stopCh, resyncerrc) +} + +// startResync periodically calls r.store.Resync() method. +// Note that this method is blocking and should be +// called in a separate goroutine. +func (r *Reflector) startResync(stopCh <-chan struct{}, cancelCh <-chan struct{}, resyncerrc chan error) { + resyncCh, cleanup := r.resyncChan() + defer func() { + cleanup() // Call the last one written into cleanup + }() + for { + select { + case <-resyncCh: + case <-stopCh: + return + case <-cancelCh: + return + } + if r.ShouldResync == nil || r.ShouldResync() { + klog.V(4).Infof("%s: forcing resync", r.name) + if err := r.store.Resync(); err != nil { + resyncerrc <- err return } - if r.ShouldResync == nil || r.ShouldResync() { - klog.V(4).Infof("%s: forcing resync", r.name) - if err := r.store.Resync(); err != nil { - resyncerrc <- err - return - } - } - cleanup() - resyncCh, cleanup = r.resyncChan() } - }() + cleanup() + resyncCh, cleanup = r.resyncChan() + } +} +// watch simply starts a watch request with the server. +func (r *Reflector) watch(w watch.Interface, stopCh <-chan struct{}, resyncerrc chan error) error { + var err error retry := NewRetryWithDeadline(r.MaxInternalErrorRetryDuration, time.Minute, apierrors.IsInternalError, r.clock) + for { // give the stopCh a chance to stop the loop, even in case of continue statements further down on errors select { @@ -298,35 +397,41 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error { default: } - timeoutSeconds := int64(minWatchTimeout.Seconds() * (rand.Float64() + 1.0)) - options := metav1.ListOptions{ - ResourceVersion: r.LastSyncResourceVersion(), - // We want to avoid situations of hanging watchers. Stop any watchers that do not - // receive any events within the timeout window. - TimeoutSeconds: &timeoutSeconds, - // To reduce load on kube-apiserver on watch restarts, you may enable watch bookmarks. - // Reflector doesn't assume bookmarks are returned at all (if the server do not support - // watch bookmarks, it will ignore this field). - AllowWatchBookmarks: true, - } - // start the clock before sending the request, since some proxies won't flush headers until after the first watch event is sent start := r.clock.Now() - w, err := r.listerWatcher.Watch(options) - if err != nil { - // If this is "connection refused" error, it means that most likely apiserver is not responsive. - // It doesn't make sense to re-list all objects because most likely we will be able to restart - // watch where we ended. - // If that's the case begin exponentially backing off and resend watch request. - // Do the same for "429" errors. - if utilnet.IsConnectionRefused(err) || apierrors.IsTooManyRequests(err) { - <-r.initConnBackoffManager.Backoff().C() - continue + + if w == nil { + timeoutSeconds := int64(minWatchTimeout.Seconds() * (rand.Float64() + 1.0)) + options := metav1.ListOptions{ + ResourceVersion: r.LastSyncResourceVersion(), + // We want to avoid situations of hanging watchers. Stop any watchers that do not + // receive any events within the timeout window. + TimeoutSeconds: &timeoutSeconds, + // To reduce load on kube-apiserver on watch restarts, you may enable watch bookmarks. + // Reflector doesn't assume bookmarks are returned at all (if the server do not support + // watch bookmarks, it will ignore this field). + AllowWatchBookmarks: true, + } + + w, err = r.listerWatcher.Watch(options) + if err != nil { + if canRetry := isWatchErrorRetriable(err); canRetry { + klog.V(4).Infof("%s: watch of %v returned %v - backing off", r.name, r.typeDescription, err) + select { + case <-stopCh: + return nil + case <-r.initConnBackoffManager.Backoff().C(): + continue + } + } + return err } - return err } - err = watchHandler(start, w, r.store, r.expectedType, r.expectedGVK, r.name, r.expectedTypeName, r.setLastSyncResourceVersion, r.clock, resyncerrc, stopCh) + err = watchHandler(start, w, r.store, r.expectedType, r.expectedGVK, r.name, r.typeDescription, r.setLastSyncResourceVersion, nil, r.clock, resyncerrc, stopCh) + // Ensure that watch will not be reused across iterations. + w.Stop() + w = nil retry.After(err) if err != nil { if err != errorStopRequested { @@ -335,16 +440,20 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error { // Don't set LastSyncResourceVersionUnavailable - LIST call with ResourceVersion=RV already // has a semantic that it returns data at least as fresh as provided RV. // So first try to LIST with setting RV to resource version of last observed object. - klog.V(4).Infof("%s: watch of %v closed with: %v", r.name, r.expectedTypeName, err) + klog.V(4).Infof("%s: watch of %v closed with: %v", r.name, r.typeDescription, err) case apierrors.IsTooManyRequests(err): - klog.V(2).Infof("%s: watch of %v returned 429 - backing off", r.name, r.expectedTypeName) - <-r.initConnBackoffManager.Backoff().C() - continue + klog.V(2).Infof("%s: watch of %v returned 429 - backing off", r.name, r.typeDescription) + select { + case <-stopCh: + return nil + case <-r.initConnBackoffManager.Backoff().C(): + continue + } case apierrors.IsInternalError(err) && retry.ShouldRetry(): - klog.V(2).Infof("%s: retrying watch of %v internal error: %v", r.name, r.expectedTypeName, err) + klog.V(2).Infof("%s: retrying watch of %v internal error: %v", r.name, r.typeDescription, err) continue default: - klog.Warningf("%s: watch of %v ended with: %v", r.name, r.expectedTypeName, err) + klog.Warningf("%s: watch of %v ended with: %v", r.name, r.typeDescription, err) } } return nil @@ -421,8 +530,8 @@ func (r *Reflector) list(stopCh <-chan struct{}) error { } initTrace.Step("Objects listed", trace.Field{Key: "error", Value: err}) if err != nil { - klog.Warningf("%s: failed to list %v: %v", r.name, r.expectedTypeName, err) - return fmt.Errorf("failed to list %v: %w", r.expectedTypeName, err) + klog.Warningf("%s: failed to list %v: %v", r.name, r.typeDescription, err) + return fmt.Errorf("failed to list %v: %w", r.typeDescription, err) } // We check if the list was paginated and if so set the paginatedResult based on that. @@ -460,6 +569,114 @@ func (r *Reflector) list(stopCh <-chan struct{}) error { return nil } +// watchList establishes a stream to get a consistent snapshot of data +// from the server as described in https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/3157-watch-list#proposal +// +// case 1: start at Most Recent (RV="", ResourceVersionMatch=ResourceVersionMatchNotOlderThan) +// Establishes a consistent stream with the server. +// That means the returned data is consistent, as if, served directly from etcd via a quorum read. +// It begins with synthetic "Added" events of all resources up to the most recent ResourceVersion. +// It ends with a synthetic "Bookmark" event containing the most recent ResourceVersion. +// After receiving a "Bookmark" event the reflector is considered to be synchronized. +// It replaces its internal store with the collected items and +// reuses the current watch requests for getting further events. +// +// case 2: start at Exact (RV>"0", ResourceVersionMatch=ResourceVersionMatchNotOlderThan) +// Establishes a stream with the server at the provided resource version. +// To establish the initial state the server begins with synthetic "Added" events. +// It ends with a synthetic "Bookmark" event containing the provided or newer resource version. +// After receiving a "Bookmark" event the reflector is considered to be synchronized. +// It replaces its internal store with the collected items and +// reuses the current watch requests for getting further events. +func (r *Reflector) watchList(stopCh <-chan struct{}) (watch.Interface, error) { + var w watch.Interface + var err error + var temporaryStore Store + var resourceVersion string + // TODO(#115478): see if this function could be turned + // into a method and see if error handling + // could be unified with the r.watch method + isErrorRetriableWithSideEffectsFn := func(err error) bool { + if canRetry := isWatchErrorRetriable(err); canRetry { + klog.V(2).Infof("%s: watch-list of %v returned %v - backing off", r.name, r.typeDescription, err) + <-r.initConnBackoffManager.Backoff().C() + return true + } + if isExpiredError(err) || isTooLargeResourceVersionError(err) { + // we tried to re-establish a watch request but the provided RV + // has either expired or it is greater than the server knows about. + // In that case we reset the RV and + // try to get a consistent snapshot from the watch cache (case 1) + r.setIsLastSyncResourceVersionUnavailable(true) + return true + } + return false + } + + initTrace := trace.New("Reflector WatchList", trace.Field{Key: "name", Value: r.name}) + defer initTrace.LogIfLong(10 * time.Second) + for { + select { + case <-stopCh: + return nil, nil + default: + } + + resourceVersion = "" + lastKnownRV := r.rewatchResourceVersion() + temporaryStore = NewStore(DeletionHandlingMetaNamespaceKeyFunc) + // TODO(#115478): large "list", slow clients, slow network, p&f + // might slow down streaming and eventually fail. + // maybe in such a case we should retry with an increased timeout? + timeoutSeconds := int64(minWatchTimeout.Seconds() * (rand.Float64() + 1.0)) + options := metav1.ListOptions{ + ResourceVersion: lastKnownRV, + AllowWatchBookmarks: true, + SendInitialEvents: pointer.Bool(true), + ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan, + TimeoutSeconds: &timeoutSeconds, + } + start := r.clock.Now() + + w, err = r.listerWatcher.Watch(options) + if err != nil { + if isErrorRetriableWithSideEffectsFn(err) { + continue + } + return nil, err + } + bookmarkReceived := pointer.Bool(false) + err = watchHandler(start, w, temporaryStore, r.expectedType, r.expectedGVK, r.name, r.typeDescription, + func(rv string) { resourceVersion = rv }, + bookmarkReceived, + r.clock, make(chan error), stopCh) + if err != nil { + w.Stop() // stop and retry with clean state + if err == errorStopRequested { + return nil, nil + } + if isErrorRetriableWithSideEffectsFn(err) { + continue + } + return nil, err + } + if *bookmarkReceived { + break + } + } + // We successfully got initial state from watch-list confirmed by the + // "k8s.io/initial-events-end" bookmark. + initTrace.Step("Objects streamed", trace.Field{Key: "count", Value: len(temporaryStore.List())}) + r.setIsLastSyncResourceVersionUnavailable(false) + if err = r.store.Replace(temporaryStore.List(), resourceVersion); err != nil { + return nil, fmt.Errorf("unable to sync watch-list result: %v", err) + } + initTrace.Step("SyncWith done") + r.setLastSyncResourceVersion(resourceVersion) + + return w, nil +} + // syncWith replaces the store's items with the given list. func (r *Reflector) syncWith(items []runtime.Object, resourceVersion string) error { found := make([]interface{}, 0, len(items)) @@ -478,15 +695,17 @@ func watchHandler(start time.Time, name string, expectedTypeName string, setLastSyncResourceVersion func(string), + exitOnInitialEventsEndBookmark *bool, clock clock.Clock, errc chan error, stopCh <-chan struct{}, ) error { eventCount := 0 - - // Stopping the watcher should be idempotent and if we return from this function there's no way - // we're coming back in with the same watch interface. - defer w.Stop() + if exitOnInitialEventsEndBookmark != nil { + // set it to false just in case somebody + // made it positive + *exitOnInitialEventsEndBookmark = false + } loop: for { @@ -541,6 +760,11 @@ loop: } case watch.Bookmark: // A `Bookmark` means watch has synced here, just update the resourceVersion + if _, ok := meta.GetAnnotations()["k8s.io/initial-events-end"]; ok { + if exitOnInitialEventsEndBookmark != nil { + *exitOnInitialEventsEndBookmark = true + } + } default: utilruntime.HandleError(fmt.Errorf("%s: unable to understand watch event %#v", name, event)) } @@ -549,6 +773,11 @@ loop: rvu.UpdateResourceVersion(resourceVersion) } eventCount++ + if exitOnInitialEventsEndBookmark != nil && *exitOnInitialEventsEndBookmark { + watchDuration := clock.Since(start) + klog.V(4).Infof("exiting %v Watch because received the bookmark that marks the end of initial events stream, total %v items received in %v", name, eventCount, watchDuration) + return nil + } } } @@ -597,6 +826,18 @@ func (r *Reflector) relistResourceVersion() string { return r.lastSyncResourceVersion } +// rewatchResourceVersion determines the resource version the reflector should start streaming from. +func (r *Reflector) rewatchResourceVersion() string { + r.lastSyncResourceVersionMutex.RLock() + defer r.lastSyncResourceVersionMutex.RUnlock() + if r.isLastSyncResourceVersionUnavailable { + // initial stream should return data at the most recent resource version. + // the returned data must be consistent i.e. as if served from etcd via a quorum read + return "" + } + return r.lastSyncResourceVersion +} + // setIsLastSyncResourceVersionUnavailable sets if the last list or watch request with lastSyncResourceVersion returned // "expired" or "too large resource version" error. func (r *Reflector) setIsLastSyncResourceVersionUnavailable(isUnavailable bool) { @@ -635,5 +876,25 @@ func isTooLargeResourceVersionError(err error) bool { return true } } + + // Matches the message returned by api server before 1.17.0 + if strings.Contains(apierr.Status().Message, "Too large resource version") { + return true + } + + return false +} + +// isWatchErrorRetriable determines if it is safe to retry +// a watch error retrieved from the server. +func isWatchErrorRetriable(err error) bool { + // If this is "connection refused" error, it means that most likely apiserver is not responsive. + // It doesn't make sense to re-list all objects because most likely we will be able to restart + // watch where we ended. + // If that's the case begin exponentially backing off and resend watch request. + // Do the same for "429" errors. + if utilnet.IsConnectionRefused(err) || apierrors.IsTooManyRequests(err) { + return true + } return false } diff --git a/vendor/k8s.io/client-go/tools/cache/shared_informer.go b/vendor/k8s.io/client-go/tools/cache/shared_informer.go index f5c7316a1d..a889fdbc36 100644 --- a/vendor/k8s.io/client-go/tools/cache/shared_informer.go +++ b/vendor/k8s.io/client-go/tools/cache/shared_informer.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/tools/cache/synctrack" "k8s.io/utils/buffer" "k8s.io/utils/clock" @@ -132,11 +133,13 @@ import ( // state, except that its ResourceVersion is replaced with a // ResourceVersion in which the object is actually absent. type SharedInformer interface { - // AddEventHandler adds an event handler to the shared informer using the shared informer's resync - // period. Events to a single handler are delivered sequentially, but there is no coordination - // between different handlers. - // It returns a registration handle for the handler that can be used to remove - // the handler again. + // AddEventHandler adds an event handler to the shared informer using + // the shared informer's resync period. Events to a single handler are + // delivered sequentially, but there is no coordination between + // different handlers. + // It returns a registration handle for the handler that can be used to + // remove the handler again, or to tell if the handler is synced (has + // seen every item in the initial list). AddEventHandler(handler ResourceEventHandler) (ResourceEventHandlerRegistration, error) // AddEventHandlerWithResyncPeriod adds an event handler to the // shared informer with the requested resync period; zero means @@ -169,6 +172,10 @@ type SharedInformer interface { // HasSynced returns true if the shared informer's store has been // informed by at least one full LIST of the authoritative state // of the informer's object collection. This is unrelated to "resync". + // + // Note that this doesn't tell you if an individual handler is synced!! + // For that, please call HasSynced on the handle returned by + // AddEventHandler. HasSynced() bool // LastSyncResourceVersion is the resource version observed when last synced with the underlying // store. The value returned is not synchronized with access to the underlying store and is not @@ -198,10 +205,7 @@ type SharedInformer interface { // // Must be set before starting the informer. // - // Note: Since the object given to the handler may be already shared with - // other goroutines, it is advisable to copy the object being - // transform before mutating it at all and returning the copy to prevent - // data races. + // Please see the comment on TransformFunc for more details. SetTransform(handler TransformFunc) error // IsStopped reports whether the informer has already been stopped. @@ -213,7 +217,14 @@ type SharedInformer interface { // Opaque interface representing the registration of ResourceEventHandler for // a SharedInformer. Must be supplied back to the same SharedInformer's // `RemoveEventHandler` to unregister the handlers. -type ResourceEventHandlerRegistration interface{} +// +// Also used to tell if the handler is synced (has had all items in the initial +// list delivered). +type ResourceEventHandlerRegistration interface { + // HasSynced reports if both the parent has synced and all pre-sync + // events have been delivered. + HasSynced() bool +} // SharedIndexInformer provides add and get Indexers ability based on SharedInformer. type SharedIndexInformer interface { @@ -223,14 +234,26 @@ type SharedIndexInformer interface { GetIndexer() Indexer } -// NewSharedInformer creates a new instance for the listwatcher. +// NewSharedInformer creates a new instance for the ListerWatcher. See NewSharedIndexInformerWithOptions for full details. func NewSharedInformer(lw ListerWatcher, exampleObject runtime.Object, defaultEventHandlerResyncPeriod time.Duration) SharedInformer { return NewSharedIndexInformer(lw, exampleObject, defaultEventHandlerResyncPeriod, Indexers{}) } -// NewSharedIndexInformer creates a new instance for the listwatcher. -// The created informer will not do resyncs if the given -// defaultEventHandlerResyncPeriod is zero. Otherwise: for each +// NewSharedIndexInformer creates a new instance for the ListerWatcher and specified Indexers. See +// NewSharedIndexInformerWithOptions for full details. +func NewSharedIndexInformer(lw ListerWatcher, exampleObject runtime.Object, defaultEventHandlerResyncPeriod time.Duration, indexers Indexers) SharedIndexInformer { + return NewSharedIndexInformerWithOptions( + lw, + exampleObject, + SharedIndexInformerOptions{ + ResyncPeriod: defaultEventHandlerResyncPeriod, + Indexers: indexers, + }, + ) +} + +// NewSharedIndexInformerWithOptions creates a new instance for the ListerWatcher. +// The created informer will not do resyncs if options.ResyncPeriod is zero. Otherwise: for each // handler that with a non-zero requested resync period, whether added // before or after the informer starts, the nominal resync period is // the requested resync period rounded up to a multiple of the @@ -238,21 +261,36 @@ func NewSharedInformer(lw ListerWatcher, exampleObject runtime.Object, defaultEv // checking period is established when the informer starts running, // and is the maximum of (a) the minimum of the resync periods // requested before the informer starts and the -// defaultEventHandlerResyncPeriod given here and (b) the constant +// options.ResyncPeriod given here and (b) the constant // `minimumResyncPeriod` defined in this file. -func NewSharedIndexInformer(lw ListerWatcher, exampleObject runtime.Object, defaultEventHandlerResyncPeriod time.Duration, indexers Indexers) SharedIndexInformer { +func NewSharedIndexInformerWithOptions(lw ListerWatcher, exampleObject runtime.Object, options SharedIndexInformerOptions) SharedIndexInformer { realClock := &clock.RealClock{} - sharedIndexInformer := &sharedIndexInformer{ + + return &sharedIndexInformer{ + indexer: NewIndexer(DeletionHandlingMetaNamespaceKeyFunc, options.Indexers), processor: &sharedProcessor{clock: realClock}, - indexer: NewIndexer(DeletionHandlingMetaNamespaceKeyFunc, indexers), listerWatcher: lw, objectType: exampleObject, - resyncCheckPeriod: defaultEventHandlerResyncPeriod, - defaultEventHandlerResyncPeriod: defaultEventHandlerResyncPeriod, - cacheMutationDetector: NewCacheMutationDetector(fmt.Sprintf("%T", exampleObject)), + objectDescription: options.ObjectDescription, + resyncCheckPeriod: options.ResyncPeriod, + defaultEventHandlerResyncPeriod: options.ResyncPeriod, clock: realClock, + cacheMutationDetector: NewCacheMutationDetector(fmt.Sprintf("%T", exampleObject)), } - return sharedIndexInformer +} + +// SharedIndexInformerOptions configures a sharedIndexInformer. +type SharedIndexInformerOptions struct { + // ResyncPeriod is the default event handler resync period and resync check + // period. If unset/unspecified, these are defaulted to 0 (do not resync). + ResyncPeriod time.Duration + + // Indexers is the sharedIndexInformer's indexers. If unset/unspecified, no indexers are configured. + Indexers Indexers + + // ObjectDescription is the sharedIndexInformer's object description. This is passed through to the + // underlying Reflector's type description. + ObjectDescription string } // InformerSynced is a function that can be used to determine if an informer has synced. This is useful for determining if caches have synced. @@ -326,12 +364,13 @@ type sharedIndexInformer struct { listerWatcher ListerWatcher - // objectType is an example object of the type this informer is - // expected to handle. Only the type needs to be right, except - // that when that is `unstructured.Unstructured` the object's - // `"apiVersion"` and `"kind"` must also be right. + // objectType is an example object of the type this informer is expected to handle. If set, an event + // with an object with a mismatching type is dropped instead of being delivered to listeners. objectType runtime.Object + // objectDescription is the description of this informer's objects. This typically defaults to + objectDescription string + // resyncCheckPeriod is how often we want the reflector's resync timer to fire so it can call // shouldResync to check if any of our listeners need a resync. resyncCheckPeriod time.Duration @@ -381,7 +420,8 @@ type updateNotification struct { } type addNotification struct { - newObj interface{} + newObj interface{} + isInInitialList bool } type deleteNotification struct { @@ -422,15 +462,17 @@ func (s *sharedIndexInformer) Run(stopCh <-chan struct{}) { fifo := NewDeltaFIFOWithOptions(DeltaFIFOOptions{ KnownObjects: s.indexer, EmitDeltaTypeReplaced: true, + Transformer: s.transform, }) cfg := &Config{ - Queue: fifo, - ListerWatcher: s.listerWatcher, - ObjectType: s.objectType, - FullResyncPeriod: s.resyncCheckPeriod, - RetryOnError: false, - ShouldResync: s.processor.shouldResync, + Queue: fifo, + ListerWatcher: s.listerWatcher, + ObjectType: s.objectType, + ObjectDescription: s.objectDescription, + FullResyncPeriod: s.resyncCheckPeriod, + RetryOnError: false, + ShouldResync: s.processor.shouldResync, Process: s.HandleDeltas, WatchErrorHandler: s.watchErrorHandler, @@ -559,7 +601,7 @@ func (s *sharedIndexInformer) AddEventHandlerWithResyncPeriod(handler ResourceEv } } - listener := newProcessListener(handler, resyncPeriod, determineResyncPeriod(resyncPeriod, s.resyncCheckPeriod), s.clock.Now(), initialBufferSize) + listener := newProcessListener(handler, resyncPeriod, determineResyncPeriod(resyncPeriod, s.resyncCheckPeriod), s.clock.Now(), initialBufferSize, s.HasSynced) if !s.started { return s.processor.addListener(listener), nil @@ -575,27 +617,35 @@ func (s *sharedIndexInformer) AddEventHandlerWithResyncPeriod(handler ResourceEv handle := s.processor.addListener(listener) for _, item := range s.indexer.List() { - listener.add(addNotification{newObj: item}) + // Note that we enqueue these notifications with the lock held + // and before returning the handle. That means there is never a + // chance for anyone to call the handle's HasSynced method in a + // state when it would falsely return true (i.e., when the + // shared informer is synced but it has not observed an Add + // with isInitialList being true, nor when the thread + // processing notifications somehow goes faster than this + // thread adding them and the counter is temporarily zero). + listener.add(addNotification{newObj: item, isInInitialList: true}) } return handle, nil } -func (s *sharedIndexInformer) HandleDeltas(obj interface{}) error { +func (s *sharedIndexInformer) HandleDeltas(obj interface{}, isInInitialList bool) error { s.blockDeltas.Lock() defer s.blockDeltas.Unlock() if deltas, ok := obj.(Deltas); ok { - return processDeltas(s, s.indexer, s.transform, deltas) + return processDeltas(s, s.indexer, deltas, isInInitialList) } return errors.New("object given as Process argument is not Deltas") } // Conforms to ResourceEventHandler -func (s *sharedIndexInformer) OnAdd(obj interface{}) { +func (s *sharedIndexInformer) OnAdd(obj interface{}, isInInitialList bool) { // Invocation of this function is locked under s.blockDeltas, so it is // save to distribute the notification s.cacheMutationDetector.AddObject(obj) - s.processor.distribute(addNotification{newObj: obj}, false) + s.processor.distribute(addNotification{newObj: obj, isInInitialList: isInInitialList}, false) } // Conforms to ResourceEventHandler @@ -817,6 +867,8 @@ type processorListener struct { handler ResourceEventHandler + syncTracker *synctrack.SingleFileTracker + // pendingNotifications is an unbounded ring buffer that holds all notifications not yet distributed. // There is one per listener, but a failing/stalled listener will have infinite pendingNotifications // added until we OOM. @@ -847,11 +899,18 @@ type processorListener struct { resyncLock sync.Mutex } -func newProcessListener(handler ResourceEventHandler, requestedResyncPeriod, resyncPeriod time.Duration, now time.Time, bufferSize int) *processorListener { +// HasSynced returns true if the source informer has synced, and all +// corresponding events have been delivered. +func (p *processorListener) HasSynced() bool { + return p.syncTracker.HasSynced() +} + +func newProcessListener(handler ResourceEventHandler, requestedResyncPeriod, resyncPeriod time.Duration, now time.Time, bufferSize int, hasSynced func() bool) *processorListener { ret := &processorListener{ nextCh: make(chan interface{}), addCh: make(chan interface{}), handler: handler, + syncTracker: &synctrack.SingleFileTracker{UpstreamHasSynced: hasSynced}, pendingNotifications: *buffer.NewRingGrowing(bufferSize), requestedResyncPeriod: requestedResyncPeriod, resyncPeriod: resyncPeriod, @@ -863,6 +922,9 @@ func newProcessListener(handler ResourceEventHandler, requestedResyncPeriod, res } func (p *processorListener) add(notification interface{}) { + if a, ok := notification.(addNotification); ok && a.isInInitialList { + p.syncTracker.Start() + } p.addCh <- notification } @@ -908,7 +970,10 @@ func (p *processorListener) run() { case updateNotification: p.handler.OnUpdate(notification.oldObj, notification.newObj) case addNotification: - p.handler.OnAdd(notification.newObj) + p.handler.OnAdd(notification.newObj, notification.isInInitialList) + if notification.isInInitialList { + p.syncTracker.Finished() + } case deleteNotification: p.handler.OnDelete(notification.oldObj) default: diff --git a/vendor/k8s.io/client-go/tools/cache/synctrack/lazy.go b/vendor/k8s.io/client-go/tools/cache/synctrack/lazy.go new file mode 100644 index 0000000000..ce51da9af3 --- /dev/null +++ b/vendor/k8s.io/client-go/tools/cache/synctrack/lazy.go @@ -0,0 +1,83 @@ +/* +Copyright 2023 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 synctrack + +import ( + "sync" + "sync/atomic" +) + +// Lazy defers the computation of `Evaluate` to when it is necessary. It is +// possible that Evaluate will be called in parallel from multiple goroutines. +type Lazy[T any] struct { + Evaluate func() (T, error) + + cache atomic.Pointer[cacheEntry[T]] +} + +type cacheEntry[T any] struct { + eval func() (T, error) + lock sync.RWMutex + result *T +} + +func (e *cacheEntry[T]) get() (T, error) { + if cur := func() *T { + e.lock.RLock() + defer e.lock.RUnlock() + return e.result + }(); cur != nil { + return *cur, nil + } + + e.lock.Lock() + defer e.lock.Unlock() + if e.result != nil { + return *e.result, nil + } + r, err := e.eval() + if err == nil { + e.result = &r + } + return r, err +} + +func (z *Lazy[T]) newCacheEntry() *cacheEntry[T] { + return &cacheEntry[T]{eval: z.Evaluate} +} + +// Notify should be called when something has changed necessitating a new call +// to Evaluate. +func (z *Lazy[T]) Notify() { z.cache.Swap(z.newCacheEntry()) } + +// Get should be called to get the current result of a call to Evaluate. If the +// current cached value is stale (due to a call to Notify), then Evaluate will +// be called synchronously. If subsequent calls to Get happen (without another +// Notify), they will all wait for the same return value. +// +// Error returns are not cached and will cause multiple calls to evaluate! +func (z *Lazy[T]) Get() (T, error) { + e := z.cache.Load() + if e == nil { + // Since we don't force a constructor, nil is a possible value. + // If multiple Gets race to set this, the swap makes sure only + // one wins. + z.cache.CompareAndSwap(nil, z.newCacheEntry()) + e = z.cache.Load() + } + return e.get() +} diff --git a/vendor/k8s.io/client-go/tools/cache/synctrack/synctrack.go b/vendor/k8s.io/client-go/tools/cache/synctrack/synctrack.go new file mode 100644 index 0000000000..3fa2beb6b7 --- /dev/null +++ b/vendor/k8s.io/client-go/tools/cache/synctrack/synctrack.go @@ -0,0 +1,120 @@ +/* +Copyright 2022 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 synctrack contains utilities for helping controllers track whether +// they are "synced" or not, that is, whether they have processed all items +// from the informer's initial list. +package synctrack + +import ( + "sync" + "sync/atomic" + + "k8s.io/apimachinery/pkg/util/sets" +) + +// AsyncTracker helps propagate HasSynced in the face of multiple worker threads. +type AsyncTracker[T comparable] struct { + UpstreamHasSynced func() bool + + lock sync.Mutex + waiting sets.Set[T] +} + +// Start should be called prior to processing each key which is part of the +// initial list. +func (t *AsyncTracker[T]) Start(key T) { + t.lock.Lock() + defer t.lock.Unlock() + if t.waiting == nil { + t.waiting = sets.New[T](key) + } else { + t.waiting.Insert(key) + } +} + +// Finished should be called when finished processing a key which was part of +// the initial list. Since keys are tracked individually, nothing bad happens +// if you call Finished without a corresponding call to Start. This makes it +// easier to use this in combination with e.g. queues which don't make it easy +// to plumb through the isInInitialList boolean. +func (t *AsyncTracker[T]) Finished(key T) { + t.lock.Lock() + defer t.lock.Unlock() + if t.waiting != nil { + t.waiting.Delete(key) + } +} + +// HasSynced returns true if the source is synced and every key present in the +// initial list has been processed. This relies on the source not considering +// itself synced until *after* it has delivered the notification for the last +// key, and that notification handler must have called Start. +func (t *AsyncTracker[T]) HasSynced() bool { + // Call UpstreamHasSynced first: it might take a lock, which might take + // a significant amount of time, and we can't hold our lock while + // waiting on that or a user is likely to get a deadlock. + if !t.UpstreamHasSynced() { + return false + } + t.lock.Lock() + defer t.lock.Unlock() + return t.waiting.Len() == 0 +} + +// SingleFileTracker helps propagate HasSynced when events are processed in +// order (i.e. via a queue). +type SingleFileTracker struct { + // Important: count is used with atomic operations so it must be 64-bit + // aligned, otherwise atomic operations will panic. Having it at the top of + // the struct will guarantee that, even on 32-bit arches. + // See https://pkg.go.dev/sync/atomic#pkg-note-BUG for more information. + count int64 + + UpstreamHasSynced func() bool +} + +// Start should be called prior to processing each key which is part of the +// initial list. +func (t *SingleFileTracker) Start() { + atomic.AddInt64(&t.count, 1) +} + +// Finished should be called when finished processing a key which was part of +// the initial list. You must never call Finished() before (or without) its +// corresponding Start(), that is a logic error that could cause HasSynced to +// return a wrong value. To help you notice this should it happen, Finished() +// will panic if the internal counter goes negative. +func (t *SingleFileTracker) Finished() { + result := atomic.AddInt64(&t.count, -1) + if result < 0 { + panic("synctrack: negative counter; this logic error means HasSynced may return incorrect value") + } +} + +// HasSynced returns true if the source is synced and every key present in the +// initial list has been processed. This relies on the source not considering +// itself synced until *after* it has delivered the notification for the last +// key, and that notification handler must have called Start. +func (t *SingleFileTracker) HasSynced() bool { + // Call UpstreamHasSynced first: it might take a lock, which might take + // a significant amount of time, and we don't want to then act on a + // stale count value. + if !t.UpstreamHasSynced() { + return false + } + return atomic.LoadInt64(&t.count) <= 0 +} diff --git a/vendor/k8s.io/client-go/tools/events/event_broadcaster.go b/vendor/k8s.io/client-go/tools/events/event_broadcaster.go index 951965e95e..e3000bf6ec 100644 --- a/vendor/k8s.io/client-go/tools/events/event_broadcaster.go +++ b/vendor/k8s.io/client-go/tools/events/event_broadcaster.go @@ -56,9 +56,11 @@ var defaultSleepDuration = 10 * time.Second // TODO: validate impact of copying and investigate hashing type eventKey struct { + eventType string action string reason string reportingController string + reportingInstance string regarding corev1.ObjectReference related corev1.ObjectReference } @@ -181,22 +183,24 @@ func (e *eventBroadcasterImpl) recordToSink(event *eventsv1.Event, clock clock.C return nil } isomorphicEvent.Series = &eventsv1.EventSeries{ - Count: 1, + Count: 2, LastObservedTime: metav1.MicroTime{Time: clock.Now()}, } - return isomorphicEvent + // Make a copy of the Event to make sure that recording it + // doesn't mess with the object stored in cache. + return isomorphicEvent.DeepCopy() } e.eventCache[eventKey] = eventCopy - return eventCopy + // Make a copy of the Event to make sure that recording it doesn't + // mess with the object stored in cache. + return eventCopy.DeepCopy() }() if evToRecord != nil { - recordedEvent := e.attemptRecording(evToRecord) - if recordedEvent != nil { - recordedEventKey := getKey(recordedEvent) - e.mu.Lock() - defer e.mu.Unlock() - e.eventCache[recordedEventKey] = recordedEvent - } + // TODO: Add a metric counting the number of recording attempts + e.attemptRecording(evToRecord) + // We don't want the new recorded Event to be reflected in the + // client's cache because server-side mutations could mess with the + // aggregation mechanism used by the client. } }() } @@ -248,6 +252,14 @@ func recordEvent(sink EventSink, event *eventsv1.Event) (*eventsv1.Event, bool) return nil, false case *errors.StatusError: if errors.IsAlreadyExists(err) { + // If we tried to create an Event from an EventSerie, it means that + // the original Patch request failed because the Event we were + // trying to patch didn't exist. If the creation failed because the + // Event now exists, it is safe to retry. This occurs when a new + // Event is emitted twice in a very short period of time. + if isEventSeries { + return nil, true + } klog.V(5).Infof("Server rejected event '%#v': '%v' (will not retry!)", event, err) } else { klog.Errorf("Server rejected event '%#v': '%v' (will not retry!)", event, err) @@ -279,9 +291,11 @@ func createPatchBytesForSeries(event *eventsv1.Event) ([]byte, error) { func getKey(event *eventsv1.Event) eventKey { key := eventKey{ + eventType: event.Type, action: event.Action, reason: event.Reason, reportingController: event.ReportingController, + reportingInstance: event.ReportingInstance, regarding: event.Regarding, } if event.Related != nil { diff --git a/vendor/k8s.io/client-go/tools/events/event_recorder.go b/vendor/k8s.io/client-go/tools/events/event_recorder.go index 132843742b..17d0532715 100644 --- a/vendor/k8s.io/client-go/tools/events/event_recorder.go +++ b/vendor/k8s.io/client-go/tools/events/event_recorder.go @@ -41,7 +41,7 @@ type recorderImpl struct { } func (recorder *recorderImpl) Eventf(regarding runtime.Object, related runtime.Object, eventtype, reason, action, note string, args ...interface{}) { - timestamp := metav1.MicroTime{time.Now()} + timestamp := metav1.MicroTime{Time: time.Now()} message := fmt.Sprintf(note, args...) refRegarding, err := reference.GetReference(recorder.scheme, regarding) if err != nil { diff --git a/vendor/k8s.io/client-go/tools/metrics/metrics.go b/vendor/k8s.io/client-go/tools/metrics/metrics.go index 6c684c7fa1..f36430dc3e 100644 --- a/vendor/k8s.io/client-go/tools/metrics/metrics.go +++ b/vendor/k8s.io/client-go/tools/metrics/metrics.go @@ -58,6 +58,12 @@ type CallsMetric interface { Increment(exitCode int, callStatus string) } +// RetryMetric counts the number of retries sent to the server +// partitioned by code, method, and host. +type RetryMetric interface { + IncrementRetry(ctx context.Context, code string, method string, host string) +} + var ( // ClientCertExpiry is the expiry time of a client certificate ClientCertExpiry ExpiryMetric = noopExpiry{} @@ -76,6 +82,9 @@ var ( // ExecPluginCalls is the number of calls made to an exec plugin, partitioned by // exit code and call status. ExecPluginCalls CallsMetric = noopCalls{} + // RequestRetry is the retry metric that tracks the number of + // retries sent to the server. + RequestRetry RetryMetric = noopRetry{} ) // RegisterOpts contains all the metrics to register. Metrics may be nil. @@ -88,6 +97,7 @@ type RegisterOpts struct { RateLimiterLatency LatencyMetric RequestResult ResultMetric ExecPluginCalls CallsMetric + RequestRetry RetryMetric } // Register registers metrics for the rest client to use. This can @@ -118,6 +128,9 @@ func Register(opts RegisterOpts) { if opts.ExecPluginCalls != nil { ExecPluginCalls = opts.ExecPluginCalls } + if opts.RequestRetry != nil { + RequestRetry = opts.RequestRetry + } }) } @@ -144,3 +157,7 @@ func (noopResult) Increment(context.Context, string, string, string) {} type noopCalls struct{} func (noopCalls) Increment(int, string) {} + +type noopRetry struct{} + +func (noopRetry) IncrementRetry(context.Context, string, string, string) {} diff --git a/vendor/k8s.io/client-go/tools/portforward/portforward.go b/vendor/k8s.io/client-go/tools/portforward/portforward.go index 6b5e3076ca..b581043f6e 100644 --- a/vendor/k8s.io/client-go/tools/portforward/portforward.go +++ b/vendor/k8s.io/client-go/tools/portforward/portforward.go @@ -37,6 +37,8 @@ import ( // TODO move to API machinery and re-unify with kubelet/server/portfoward const PortForwardProtocolV1Name = "portforward.k8s.io" +var ErrLostConnectionToPod = errors.New("lost connection to pod") + // PortForwarder knows how to listen for local connections and forward them to // a remote pod via an upgraded HTTP request. type PortForwarder struct { @@ -230,7 +232,7 @@ func (pf *PortForwarder) forward() error { select { case <-pf.stopChan: case <-pf.streamConn.CloseChan(): - runtime.HandleError(errors.New("lost connection to pod")) + return ErrLostConnectionToPod } return nil diff --git a/vendor/k8s.io/client-go/tools/record/event.go b/vendor/k8s.io/client-go/tools/record/event.go index 998bf8dfb6..4899b362df 100644 --- a/vendor/k8s.io/client-go/tools/record/event.go +++ b/vendor/k8s.io/client-go/tools/record/event.go @@ -17,6 +17,7 @@ limitations under the License. package record import ( + "context" "fmt" "math/rand" "time" @@ -132,7 +133,9 @@ type EventBroadcaster interface { // with the event source set to the given event source. NewRecorder(scheme *runtime.Scheme, source v1.EventSource) EventRecorder - // Shutdown shuts down the broadcaster + // Shutdown shuts down the broadcaster. Once the broadcaster is shut + // down, it will only try to record an event in a sink once before + // giving up on it with an error message. Shutdown() } @@ -157,31 +160,34 @@ func (a *EventRecorderAdapter) Eventf(regarding, _ runtime.Object, eventtype, re // Creates a new event broadcaster. func NewBroadcaster() EventBroadcaster { - return &eventBroadcasterImpl{ - Broadcaster: watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), - sleepDuration: defaultSleepDuration, - } + return newEventBroadcaster(watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), defaultSleepDuration) } func NewBroadcasterForTests(sleepDuration time.Duration) EventBroadcaster { - return &eventBroadcasterImpl{ - Broadcaster: watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), - sleepDuration: sleepDuration, - } + return newEventBroadcaster(watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), sleepDuration) } func NewBroadcasterWithCorrelatorOptions(options CorrelatorOptions) EventBroadcaster { - return &eventBroadcasterImpl{ - Broadcaster: watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), - sleepDuration: defaultSleepDuration, - options: options, + eventBroadcaster := newEventBroadcaster(watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), defaultSleepDuration) + eventBroadcaster.options = options + return eventBroadcaster +} + +func newEventBroadcaster(broadcaster *watch.Broadcaster, sleepDuration time.Duration) *eventBroadcasterImpl { + eventBroadcaster := &eventBroadcasterImpl{ + Broadcaster: broadcaster, + sleepDuration: sleepDuration, } + eventBroadcaster.cancelationCtx, eventBroadcaster.cancel = context.WithCancel(context.Background()) + return eventBroadcaster } type eventBroadcasterImpl struct { *watch.Broadcaster - sleepDuration time.Duration - options CorrelatorOptions + sleepDuration time.Duration + options CorrelatorOptions + cancelationCtx context.Context + cancel func() } // StartRecordingToSink starts sending events received from the specified eventBroadcaster to the given sink. @@ -191,15 +197,16 @@ func (e *eventBroadcasterImpl) StartRecordingToSink(sink EventSink) watch.Interf eventCorrelator := NewEventCorrelatorWithOptions(e.options) return e.StartEventWatcher( func(event *v1.Event) { - recordToSink(sink, event, eventCorrelator, e.sleepDuration) + e.recordToSink(sink, event, eventCorrelator) }) } func (e *eventBroadcasterImpl) Shutdown() { e.Broadcaster.Shutdown() + e.cancel() } -func recordToSink(sink EventSink, event *v1.Event, eventCorrelator *EventCorrelator, sleepDuration time.Duration) { +func (e *eventBroadcasterImpl) recordToSink(sink EventSink, event *v1.Event, eventCorrelator *EventCorrelator) { // Make a copy before modification, because there could be multiple listeners. // Events are safe to copy like this. eventCopy := *event @@ -221,12 +228,18 @@ func recordToSink(sink EventSink, event *v1.Event, eventCorrelator *EventCorrela klog.Errorf("Unable to write event '%#v' (retry limit exceeded!)", event) break } + // Randomize the first sleep so that various clients won't all be // synced up if the master goes down. + delay := e.sleepDuration if tries == 1 { - time.Sleep(time.Duration(float64(sleepDuration) * rand.Float64())) - } else { - time.Sleep(sleepDuration) + delay = time.Duration(float64(delay) * rand.Float64()) + } + select { + case <-e.cancelationCtx.Done(): + klog.Errorf("Unable to write event '%#v' (broadcaster is shut down)", event) + return + case <-time.After(delay): } } } diff --git a/vendor/k8s.io/client-go/tools/record/fake.go b/vendor/k8s.io/client-go/tools/record/fake.go index 0b3f344a97..fda4ad8ff8 100644 --- a/vendor/k8s.io/client-go/tools/record/fake.go +++ b/vendor/k8s.io/client-go/tools/record/fake.go @@ -41,20 +41,31 @@ func objectString(object runtime.Object, includeObject bool) string { ) } -func (f *FakeRecorder) Event(object runtime.Object, eventtype, reason, message string) { - if f.Events != nil { - f.Events <- fmt.Sprintf("%s %s %s%s", eventtype, reason, message, objectString(object, f.IncludeObject)) +func annotationsString(annotations map[string]string) string { + if len(annotations) == 0 { + return "" + } else { + return " " + fmt.Sprint(annotations) } } -func (f *FakeRecorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) { +func (f *FakeRecorder) writeEvent(object runtime.Object, annotations map[string]string, eventtype, reason, messageFmt string, args ...interface{}) { if f.Events != nil { - f.Events <- fmt.Sprintf(eventtype+" "+reason+" "+messageFmt, args...) + objectString(object, f.IncludeObject) + f.Events <- fmt.Sprintf(eventtype+" "+reason+" "+messageFmt, args...) + + objectString(object, f.IncludeObject) + annotationsString(annotations) } } +func (f *FakeRecorder) Event(object runtime.Object, eventtype, reason, message string) { + f.writeEvent(object, nil, eventtype, reason, "%s", message) +} + +func (f *FakeRecorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) { + f.writeEvent(object, nil, eventtype, reason, messageFmt, args...) +} + func (f *FakeRecorder) AnnotatedEventf(object runtime.Object, annotations map[string]string, eventtype, reason, messageFmt string, args ...interface{}) { - f.Eventf(object, eventtype, reason, messageFmt, args...) + f.writeEvent(object, annotations, eventtype, reason, messageFmt, args...) } // NewFakeRecorder creates new fake event recorder with event channel with diff --git a/vendor/k8s.io/client-go/tools/watch/until.go b/vendor/k8s.io/client-go/tools/watch/until.go index 81d4ff0ddf..a2474556b0 100644 --- a/vendor/k8s.io/client-go/tools/watch/until.go +++ b/vendor/k8s.io/client-go/tools/watch/until.go @@ -101,8 +101,7 @@ func UntilWithoutRetry(ctx context.Context, watcher watch.Interface, conditions // It guarantees you to see all events and in the order they happened. // Due to this guarantee there is no way it can deal with 'Resource version too old error'. It will fail in this case. // (See `UntilWithSync` if you'd prefer to recover from all the errors including RV too old by re-listing -// -// those items. In normal code you should care about being level driven so you'd not care about not seeing all the edges.) +// those items. In normal code you should care about being level driven so you'd not care about not seeing all the edges.) // // The most frequent usage for Until would be a test where you want to verify exact order of events ("edges"). func Until(ctx context.Context, initialResourceVersion string, watcherClient cache.Watcher, conditions ...ConditionFunc) (*watch.Event, error) { @@ -137,7 +136,7 @@ func UntilWithSync(ctx context.Context, lw cache.ListerWatcher, objType runtime. if precondition != nil { if !cache.WaitForCacheSync(ctx.Done(), informer.HasSynced) { - return nil, fmt.Errorf("UntilWithSync: unable to sync caches: %v", ctx.Err()) + return nil, fmt.Errorf("UntilWithSync: unable to sync caches: %w", ctx.Err()) } done, err := precondition(indexer) diff --git a/vendor/k8s.io/client-go/transport/cache.go b/vendor/k8s.io/client-go/transport/cache.go index 9d2889d194..edcc6d1d48 100644 --- a/vendor/k8s.io/client-go/transport/cache.go +++ b/vendor/k8s.io/client-go/transport/cache.go @@ -109,7 +109,7 @@ func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) { // If we use are reloading files, we need to handle certificate rotation properly // TODO(jackkleeman): We can also add rotation here when config.HasCertCallback() is true - if config.TLS.ReloadTLSFiles { + if config.TLS.ReloadTLSFiles && tlsConfig != nil && tlsConfig.GetClientCertificate != nil { dynamicCertDialer := certRotatingDialer(tlsConfig.GetClientCertificate, dial) tlsConfig.GetClientCertificate = dynamicCertDialer.GetClientCertificate dial = dynamicCertDialer.connDialer.DialContext diff --git a/vendor/k8s.io/client-go/util/cert/cert.go b/vendor/k8s.io/client-go/util/cert/cert.go index 7196cf8900..4be1dfe493 100644 --- a/vendor/k8s.io/client-go/util/cert/cert.go +++ b/vendor/k8s.io/client-go/util/cert/cert.go @@ -191,7 +191,7 @@ func GenerateSelfSignedCertKeyWithFixtures(host string, alternateIPs []net.IP, a if err := os.WriteFile(certFixturePath, certBuffer.Bytes(), 0644); err != nil { return nil, nil, fmt.Errorf("failed to write cert fixture to %s: %v", certFixturePath, err) } - if err := os.WriteFile(keyFixturePath, keyBuffer.Bytes(), 0644); err != nil { + if err := os.WriteFile(keyFixturePath, keyBuffer.Bytes(), 0600); err != nil { return nil, nil, fmt.Errorf("failed to write key fixture to %s: %v", certFixturePath, err) } } diff --git a/vendor/k8s.io/client-go/util/testing/fake_openapi_handler.go b/vendor/k8s.io/client-go/util/testing/fake_openapi_handler.go index b6e4d6683b..a7b0d590bb 100644 --- a/vendor/k8s.io/client-go/util/testing/fake_openapi_handler.go +++ b/vendor/k8s.io/client-go/util/testing/fake_openapi_handler.go @@ -41,21 +41,17 @@ type FakeOpenAPIServer struct { // API server. // // specsPath - Give a path to some test data organized so that each GroupVersion +// has its own OpenAPI V3 JSON file. // -// has its own OpenAPI V3 JSON file. -// i.e. apps/v1beta1 is stored in /apps/v1beta1.json +// i.e. apps/v1beta1 is stored in /apps/v1beta1.json func NewFakeOpenAPIV3Server(specsPath string) (*FakeOpenAPIServer, error) { mux := &testMux{ counts: map[string]int{}, } server := httptest.NewServer(mux) - openAPIVersionedService, err := handler3.NewOpenAPIService(nil) - if err != nil { - return nil, err - } - - err = openAPIVersionedService.RegisterOpenAPIV3VersionedService("/openapi/v3", mux) + openAPIVersionedService := handler3.NewOpenAPIService() + err := openAPIVersionedService.RegisterOpenAPIV3VersionedService("/openapi/v3", mux) if err != nil { return nil, err } diff --git a/vendor/k8s.io/client-go/util/workqueue/delaying_queue.go b/vendor/k8s.io/client-go/util/workqueue/delaying_queue.go index 26eacc2ba7..c1df720302 100644 --- a/vendor/k8s.io/client-go/util/workqueue/delaying_queue.go +++ b/vendor/k8s.io/client-go/util/workqueue/delaying_queue.go @@ -33,38 +33,81 @@ type DelayingInterface interface { AddAfter(item interface{}, duration time.Duration) } +// DelayingQueueConfig specifies optional configurations to customize a DelayingInterface. +type DelayingQueueConfig struct { + // Name for the queue. If unnamed, the metrics will not be registered. + Name string + + // MetricsProvider optionally allows specifying a metrics provider to use for the queue + // instead of the global provider. + MetricsProvider MetricsProvider + + // Clock optionally allows injecting a real or fake clock for testing purposes. + Clock clock.WithTicker + + // Queue optionally allows injecting custom queue Interface instead of the default one. + Queue Interface +} + // NewDelayingQueue constructs a new workqueue with delayed queuing ability. // NewDelayingQueue does not emit metrics. For use with a MetricsProvider, please use -// NewNamedDelayingQueue instead. +// NewDelayingQueueWithConfig instead and specify a name. func NewDelayingQueue() DelayingInterface { - return NewDelayingQueueWithCustomClock(clock.RealClock{}, "") + return NewDelayingQueueWithConfig(DelayingQueueConfig{}) +} + +// NewDelayingQueueWithConfig constructs a new workqueue with options to +// customize different properties. +func NewDelayingQueueWithConfig(config DelayingQueueConfig) DelayingInterface { + if config.Clock == nil { + config.Clock = clock.RealClock{} + } + + if config.Queue == nil { + config.Queue = NewWithConfig(QueueConfig{ + Name: config.Name, + MetricsProvider: config.MetricsProvider, + Clock: config.Clock, + }) + } + + return newDelayingQueue(config.Clock, config.Queue, config.Name, config.MetricsProvider) } // NewDelayingQueueWithCustomQueue constructs a new workqueue with ability to // inject custom queue Interface instead of the default one +// Deprecated: Use NewDelayingQueueWithConfig instead. func NewDelayingQueueWithCustomQueue(q Interface, name string) DelayingInterface { - return newDelayingQueue(clock.RealClock{}, q, name) + return NewDelayingQueueWithConfig(DelayingQueueConfig{ + Name: name, + Queue: q, + }) } -// NewNamedDelayingQueue constructs a new named workqueue with delayed queuing ability +// NewNamedDelayingQueue constructs a new named workqueue with delayed queuing ability. +// Deprecated: Use NewDelayingQueueWithConfig instead. func NewNamedDelayingQueue(name string) DelayingInterface { - return NewDelayingQueueWithCustomClock(clock.RealClock{}, name) + return NewDelayingQueueWithConfig(DelayingQueueConfig{Name: name}) } // NewDelayingQueueWithCustomClock constructs a new named workqueue -// with ability to inject real or fake clock for testing purposes +// with ability to inject real or fake clock for testing purposes. +// Deprecated: Use NewDelayingQueueWithConfig instead. func NewDelayingQueueWithCustomClock(clock clock.WithTicker, name string) DelayingInterface { - return newDelayingQueue(clock, NewNamed(name), name) + return NewDelayingQueueWithConfig(DelayingQueueConfig{ + Name: name, + Clock: clock, + }) } -func newDelayingQueue(clock clock.WithTicker, q Interface, name string) *delayingType { +func newDelayingQueue(clock clock.WithTicker, q Interface, name string, provider MetricsProvider) *delayingType { ret := &delayingType{ Interface: q, clock: clock, heartbeat: clock.NewTicker(maxWait), stopCh: make(chan struct{}), waitingForAddCh: make(chan *waitFor, 1000), - metrics: newRetryMetrics(name), + metrics: newRetryMetrics(name, provider), } go ret.waitingLoop() diff --git a/vendor/k8s.io/client-go/util/workqueue/metrics.go b/vendor/k8s.io/client-go/util/workqueue/metrics.go index 4b0a69616d..f012ccc554 100644 --- a/vendor/k8s.io/client-go/util/workqueue/metrics.go +++ b/vendor/k8s.io/client-go/util/workqueue/metrics.go @@ -244,13 +244,18 @@ func (f *queueMetricsFactory) newQueueMetrics(name string, clock clock.Clock) qu } } -func newRetryMetrics(name string) retryMetrics { +func newRetryMetrics(name string, provider MetricsProvider) retryMetrics { var ret *defaultRetryMetrics if len(name) == 0 { return ret } + + if provider == nil { + provider = globalMetricsFactory.metricsProvider + } + return &defaultRetryMetrics{ - retries: globalMetricsFactory.metricsProvider.NewRetriesMetric(name), + retries: provider.NewRetriesMetric(name), } } diff --git a/vendor/k8s.io/client-go/util/workqueue/queue.go b/vendor/k8s.io/client-go/util/workqueue/queue.go index 6f7063269f..380c064552 100644 --- a/vendor/k8s.io/client-go/util/workqueue/queue.go +++ b/vendor/k8s.io/client-go/util/workqueue/queue.go @@ -33,17 +33,60 @@ type Interface interface { ShuttingDown() bool } +// QueueConfig specifies optional configurations to customize an Interface. +type QueueConfig struct { + // Name for the queue. If unnamed, the metrics will not be registered. + Name string + + // MetricsProvider optionally allows specifying a metrics provider to use for the queue + // instead of the global provider. + MetricsProvider MetricsProvider + + // Clock ability to inject real or fake clock for testing purposes. + Clock clock.WithTicker +} + // New constructs a new work queue (see the package comment). func New() *Type { - return NewNamed("") + return NewWithConfig(QueueConfig{ + Name: "", + }) } +// NewWithConfig constructs a new workqueue with ability to +// customize different properties. +func NewWithConfig(config QueueConfig) *Type { + return newQueueWithConfig(config, defaultUnfinishedWorkUpdatePeriod) +} + +// NewNamed creates a new named queue. +// Deprecated: Use NewWithConfig instead. func NewNamed(name string) *Type { - rc := clock.RealClock{} + return NewWithConfig(QueueConfig{ + Name: name, + }) +} + +// newQueueWithConfig constructs a new named workqueue +// with the ability to customize different properties for testing purposes +func newQueueWithConfig(config QueueConfig, updatePeriod time.Duration) *Type { + var metricsFactory *queueMetricsFactory + if config.MetricsProvider != nil { + metricsFactory = &queueMetricsFactory{ + metricsProvider: config.MetricsProvider, + } + } else { + metricsFactory = &globalMetricsFactory + } + + if config.Clock == nil { + config.Clock = clock.RealClock{} + } + return newQueue( - rc, - globalMetricsFactory.newQueueMetrics(name, rc), - defaultUnfinishedWorkUpdatePeriod, + config.Clock, + metricsFactory.newQueueMetrics(config.Name, config.Clock), + updatePeriod, ) } diff --git a/vendor/k8s.io/client-go/util/workqueue/rate_limiting_queue.go b/vendor/k8s.io/client-go/util/workqueue/rate_limiting_queue.go index 91cd33f193..3e4016fb04 100644 --- a/vendor/k8s.io/client-go/util/workqueue/rate_limiting_queue.go +++ b/vendor/k8s.io/client-go/util/workqueue/rate_limiting_queue.go @@ -16,6 +16,8 @@ limitations under the License. package workqueue +import "k8s.io/utils/clock" + // RateLimitingInterface is an interface that rate limits items being added to the queue. type RateLimitingInterface interface { DelayingInterface @@ -32,29 +34,68 @@ type RateLimitingInterface interface { NumRequeues(item interface{}) int } +// RateLimitingQueueConfig specifies optional configurations to customize a RateLimitingInterface. + +type RateLimitingQueueConfig struct { + // Name for the queue. If unnamed, the metrics will not be registered. + Name string + + // MetricsProvider optionally allows specifying a metrics provider to use for the queue + // instead of the global provider. + MetricsProvider MetricsProvider + + // Clock optionally allows injecting a real or fake clock for testing purposes. + Clock clock.WithTicker + + // DelayingQueue optionally allows injecting custom delaying queue DelayingInterface instead of the default one. + DelayingQueue DelayingInterface +} + // NewRateLimitingQueue constructs a new workqueue with rateLimited queuing ability // Remember to call Forget! If you don't, you may end up tracking failures forever. // NewRateLimitingQueue does not emit metrics. For use with a MetricsProvider, please use -// NewNamedRateLimitingQueue instead. +// NewRateLimitingQueueWithConfig instead and specify a name. func NewRateLimitingQueue(rateLimiter RateLimiter) RateLimitingInterface { + return NewRateLimitingQueueWithConfig(rateLimiter, RateLimitingQueueConfig{}) +} + +// NewRateLimitingQueueWithConfig constructs a new workqueue with rateLimited queuing ability +// with options to customize different properties. +// Remember to call Forget! If you don't, you may end up tracking failures forever. +func NewRateLimitingQueueWithConfig(rateLimiter RateLimiter, config RateLimitingQueueConfig) RateLimitingInterface { + if config.Clock == nil { + config.Clock = clock.RealClock{} + } + + if config.DelayingQueue == nil { + config.DelayingQueue = NewDelayingQueueWithConfig(DelayingQueueConfig{ + Name: config.Name, + MetricsProvider: config.MetricsProvider, + Clock: config.Clock, + }) + } + return &rateLimitingType{ - DelayingInterface: NewDelayingQueue(), + DelayingInterface: config.DelayingQueue, rateLimiter: rateLimiter, } } +// NewNamedRateLimitingQueue constructs a new named workqueue with rateLimited queuing ability. +// Deprecated: Use NewRateLimitingQueueWithConfig instead. func NewNamedRateLimitingQueue(rateLimiter RateLimiter, name string) RateLimitingInterface { - return &rateLimitingType{ - DelayingInterface: NewNamedDelayingQueue(name), - rateLimiter: rateLimiter, - } + return NewRateLimitingQueueWithConfig(rateLimiter, RateLimitingQueueConfig{ + Name: name, + }) } +// NewRateLimitingQueueWithDelayingInterface constructs a new named workqueue with rateLimited queuing ability +// with the option to inject a custom delaying queue instead of the default one. +// Deprecated: Use NewRateLimitingQueueWithConfig instead. func NewRateLimitingQueueWithDelayingInterface(di DelayingInterface, rateLimiter RateLimiter) RateLimitingInterface { - return &rateLimitingType{ - DelayingInterface: di, - rateLimiter: rateLimiter, - } + return NewRateLimitingQueueWithConfig(rateLimiter, RateLimitingQueueConfig{ + DelayingQueue: di, + }) } // rateLimitingType wraps an Interface and provides rateLimited re-enquing diff --git a/vendor/k8s.io/cloud-provider/app/config/config.go b/vendor/k8s.io/cloud-provider/app/config/config.go new file mode 100644 index 0000000000..20f1d0ef9e --- /dev/null +++ b/vendor/k8s.io/cloud-provider/app/config/config.go @@ -0,0 +1,83 @@ +/* +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 config + +import ( + apiserver "k8s.io/apiserver/pkg/server" + "k8s.io/client-go/informers" + clientset "k8s.io/client-go/kubernetes" + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/record" + cloudprovider "k8s.io/cloud-provider" + "k8s.io/cloud-provider/config" +) + +// Config is the main context object for the cloud controller manager. +type Config struct { + ComponentConfig config.CloudControllerManagerConfiguration + + SecureServing *apiserver.SecureServingInfo + // LoopbackClientConfig is a config for a privileged loopback connection + LoopbackClientConfig *restclient.Config + + Authentication apiserver.AuthenticationInfo + Authorization apiserver.AuthorizationInfo + + // WebhookSecureServing is a separate SecureServing configuration from + // healthz, configz, and metrics. + WebhookSecureServing *apiserver.SecureServingInfo + + // the general kube client + Client *clientset.Clientset + + // the rest config for the master + Kubeconfig *restclient.Config + + // EventBroadcaster is broadcaster events to all sinks. + EventBroadcaster record.EventBroadcaster + + // EventRecord is a sink for events. + EventRecorder record.EventRecorder + + // ClientBuilder will provide a client for this controller to use + ClientBuilder cloudprovider.ControllerClientBuilder + + // VersionedClient will provide a client for informers + VersionedClient clientset.Interface + + // SharedInformers gives access to informers for the controller. + SharedInformers informers.SharedInformerFactory +} + +type completedConfig struct { + *Config +} + +// CompletedConfig same as Config, just to swap private object. +type CompletedConfig struct { + // Embed a private pointer that cannot be instantiated outside of this package. + *completedConfig +} + +// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver. +func (c *Config) Complete() *CompletedConfig { + cc := completedConfig{c} + + apiserver.AuthorizeClientBearerToken(c.LoopbackClientConfig, &c.Authentication, &c.Authorization) + + return &CompletedConfig{&cc} +} diff --git a/vendor/k8s.io/cloud-provider/cloud.go b/vendor/k8s.io/cloud-provider/cloud.go index 44c62ccc03..7e7bf9dfab 100644 --- a/vendor/k8s.io/cloud-provider/cloud.go +++ b/vendor/k8s.io/cloud-provider/cloud.go @@ -218,6 +218,11 @@ type Route struct { Name string // TargetNode is the NodeName of the target instance. TargetNode types.NodeName + // EnableNodeAddresses is a feature gate for TargetNodeAddresses. If false, ignore TargetNodeAddresses. + // Without this, if users haven't updated their cloud-provider, reconcile() will delete and create same route every time. + EnableNodeAddresses bool + // TargetNodeAddresses are the Node IPs of the target Node. + TargetNodeAddresses []v1.NodeAddress // DestinationCIDR is the CIDR format IP range that this routing rule // applies to. DestinationCIDR string diff --git a/vendor/k8s.io/cloud-provider/config/doc.go b/vendor/k8s.io/cloud-provider/config/doc.go new file mode 100644 index 0000000000..73322994fa --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/doc.go @@ -0,0 +1,20 @@ +/* +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. +*/ + +// +k8s:deepcopy-gen=package +// +groupName=cloudcontrollermanager.config.k8s.io + +package config // import "k8s.io/cloud-provider/config" diff --git a/vendor/k8s.io/cloud-provider/config/install/install.go b/vendor/k8s.io/cloud-provider/config/install/install.go new file mode 100644 index 0000000000..b07a9f0510 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/install/install.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 install + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/cloud-provider/config" + "k8s.io/cloud-provider/config/v1alpha1" +) + +var ( + // Scheme defines methods for serializing and deserializing API objects. + Scheme = runtime.NewScheme() + // Codecs provides methods for retrieving codecs and serializers for specific + // versions and content types. + Codecs = serializer.NewCodecFactory(Scheme) +) + +func init() { + Install(Scheme) +} + +// Install adds the types of this group into the given scheme. +func Install(scheme *runtime.Scheme) { + utilruntime.Must(config.AddToScheme(scheme)) + utilruntime.Must(v1alpha1.AddToScheme(scheme)) + utilruntime.Must(scheme.SetVersionPriority(v1alpha1.SchemeGroupVersion)) +} diff --git a/vendor/k8s.io/cloud-provider/config/register.go b/vendor/k8s.io/cloud-provider/config/register.go new file mode 100644 index 0000000000..3f14ec59b5 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/register.go @@ -0,0 +1,42 @@ +/* +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 config + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name used in this package +const GroupName = "cloudcontrollermanager.config.k8s.io" + +var ( + // SchemeGroupVersion is group version used to register these objects + SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal} + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = SchemeBuilder.AddToScheme +) + +// addKnownTypes registers known types to the given scheme +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &CloudControllerManagerConfiguration{}, + ) + return nil +} diff --git a/vendor/k8s.io/cloud-provider/config/types.go b/vendor/k8s.io/cloud-provider/config/types.go new file mode 100644 index 0000000000..1337162195 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/types.go @@ -0,0 +1,103 @@ +/* +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 config + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + nodeconfig "k8s.io/cloud-provider/controllers/node/config" + serviceconfig "k8s.io/cloud-provider/controllers/service/config" + cmconfig "k8s.io/controller-manager/config" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CloudControllerManagerConfiguration contains elements describing cloud-controller manager. +type CloudControllerManagerConfiguration struct { + metav1.TypeMeta + + // Generic holds configuration for a generic controller-manager + Generic cmconfig.GenericControllerManagerConfiguration + // KubeCloudSharedConfiguration holds configuration for shared related features + // both in cloud controller manager and kube-controller manager. + KubeCloudShared KubeCloudSharedConfiguration + + // NodeController holds configuration for node controller + // related features. + NodeController nodeconfig.NodeControllerConfiguration + + // ServiceControllerConfiguration holds configuration for ServiceController + // related features. + ServiceController serviceconfig.ServiceControllerConfiguration + + // NodeStatusUpdateFrequency is the frequency at which the controller updates nodes' status + NodeStatusUpdateFrequency metav1.Duration + + // Webhook is the configuration for cloud-controller-manager hosted webhooks + Webhook WebhookConfiguration +} + +// KubeCloudSharedConfiguration contains elements shared by both kube-controller manager +// and cloud-controller manager, but not genericconfig. +type KubeCloudSharedConfiguration struct { + // CloudProviderConfiguration holds configuration for CloudProvider related features. + CloudProvider CloudProviderConfiguration + // externalCloudVolumePlugin specifies the plugin to use when cloudProvider is "external". + // It is currently used by the in repo cloud providers to handle node and volume control in the KCM. + ExternalCloudVolumePlugin string + // useServiceAccountCredentials indicates whether controllers should be run with + // individual service account credentials. + UseServiceAccountCredentials bool + // run with untagged cloud instances + AllowUntaggedCloud bool + // routeReconciliationPeriod is the period for reconciling routes created for Nodes by cloud provider.. + RouteReconciliationPeriod metav1.Duration + // nodeMonitorPeriod is the period for syncing NodeStatus in NodeController. + NodeMonitorPeriod metav1.Duration + // clusterName is the instance prefix for the cluster. + ClusterName string + // clusterCIDR is CIDR Range for Pods in cluster. + ClusterCIDR string + // AllocateNodeCIDRs enables CIDRs for Pods to be allocated and, if + // ConfigureCloudRoutes is true, to be set on the cloud provider. + AllocateNodeCIDRs bool + // CIDRAllocatorType determines what kind of pod CIDR allocator will be used. + CIDRAllocatorType string + // configureCloudRoutes enables CIDRs allocated with allocateNodeCIDRs + // to be configured on the cloud provider. + ConfigureCloudRoutes bool + // nodeSyncPeriod is the period for syncing nodes from cloudprovider. Longer + // periods will result in fewer calls to cloud provider, but may delay addition + // of new nodes to cluster. + NodeSyncPeriod metav1.Duration +} + +// CloudProviderConfiguration contains basically elements about cloud provider. +type CloudProviderConfiguration struct { + // Name is the provider for cloud services. + Name string + // cloudConfigFile is the path to the cloud provider configuration file. + CloudConfigFile string +} + +type WebhookConfiguration struct { + // Webhooks is the list of webhooks to enable or disable + // '*' means "all enabled by default webhooks" + // 'foo' means "enable 'foo'" + // '-foo' means "disable 'foo'" + // first item for a particular name wins + Webhooks []string +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/conversion.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/conversion.go new file mode 100644 index 0000000000..41240f7af1 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/conversion.go @@ -0,0 +1,49 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/conversion" + cpconfig "k8s.io/cloud-provider/config" +) + +// Important! The public back-and-forth conversion functions for the types in this generic +// package with ComponentConfig types need to be manually exposed like this in order for +// other packages that reference this package to be able to call these conversion functions +// in an autogenerated manner. +// TODO: Fix the bug in conversion-gen so it automatically discovers these Convert_* functions +// in autogenerated code as well. + +// Convert_v1alpha1_KubeCloudSharedConfiguration_To_config_KubeCloudSharedConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_KubeCloudSharedConfiguration_To_config_KubeCloudSharedConfiguration(in *KubeCloudSharedConfiguration, out *cpconfig.KubeCloudSharedConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_KubeCloudSharedConfiguration_To_config_KubeCloudSharedConfiguration(in, out, s) +} + +// Convert_config_KubeCloudSharedConfiguration_To_v1alpha1_KubeCloudSharedConfiguration is an autogenerated conversion function. +func Convert_config_KubeCloudSharedConfiguration_To_v1alpha1_KubeCloudSharedConfiguration(in *cpconfig.KubeCloudSharedConfiguration, out *KubeCloudSharedConfiguration, s conversion.Scope) error { + return autoConvert_config_KubeCloudSharedConfiguration_To_v1alpha1_KubeCloudSharedConfiguration(in, out, s) +} + +// Convert_v1alpha1_CloudProviderConfiguration_To_config_CloudProviderConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_CloudProviderConfiguration_To_config_CloudProviderConfiguration(in *CloudProviderConfiguration, out *cpconfig.CloudProviderConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_CloudProviderConfiguration_To_config_CloudProviderConfiguration(in, out, s) +} + +// Convert_config_CloudProviderConfiguration_To_v1alpha1_CloudProviderConfiguration is an autogenerated conversion function. +func Convert_config_CloudProviderConfiguration_To_v1alpha1_CloudProviderConfiguration(in *cpconfig.CloudProviderConfiguration, out *CloudProviderConfiguration, s conversion.Scope) error { + return autoConvert_config_CloudProviderConfiguration_To_v1alpha1_CloudProviderConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/defaults.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/defaults.go new file mode 100644 index 0000000000..c7f4760b47 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/defaults.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 v1alpha1 + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + nodeconfigv1alpha1 "k8s.io/cloud-provider/controllers/node/config/v1alpha1" + serviceconfigv1alpha1 "k8s.io/cloud-provider/controllers/service/config/v1alpha1" + cmconfigv1alpha1 "k8s.io/controller-manager/config/v1alpha1" + utilpointer "k8s.io/utils/pointer" +) + +func addDefaultingFuncs(scheme *runtime.Scheme) error { + return RegisterDefaults(scheme) +} + +func SetDefaults_CloudControllerManagerConfiguration(obj *CloudControllerManagerConfiguration) { + zero := metav1.Duration{} + if obj.NodeStatusUpdateFrequency == zero { + obj.NodeStatusUpdateFrequency = metav1.Duration{Duration: 5 * time.Minute} + } + + // These defaults override the recommended defaults from the apimachineryconfigv1alpha1 package that are applied automatically + // These client-connection defaults are specific to the cloud-controller-manager + if obj.Generic.ClientConnection.QPS == 0 { + obj.Generic.ClientConnection.QPS = 20 + } + if obj.Generic.ClientConnection.Burst == 0 { + obj.Generic.ClientConnection.Burst = 30 + } + + // Use the default RecommendedDefaultGenericControllerManagerConfiguration options + cmconfigv1alpha1.RecommendedDefaultGenericControllerManagerConfiguration(&obj.Generic) + // Use the default RecommendedDefaultServiceControllerConfiguration options + serviceconfigv1alpha1.RecommendedDefaultServiceControllerConfiguration(&obj.ServiceController) + // Use the default RecommendedDefaultNodeControllerConfiguration options + nodeconfigv1alpha1.RecommendedDefaultNodeControllerConfiguration(&obj.NodeController) +} + +func SetDefaults_KubeCloudSharedConfiguration(obj *KubeCloudSharedConfiguration) { + zero := metav1.Duration{} + if obj.NodeMonitorPeriod == zero { + obj.NodeMonitorPeriod = metav1.Duration{Duration: 5 * time.Second} + } + if obj.ClusterName == "" { + obj.ClusterName = "kubernetes" + } + if obj.ConfigureCloudRoutes == nil { + obj.ConfigureCloudRoutes = utilpointer.BoolPtr(true) + } + if obj.RouteReconciliationPeriod == zero { + obj.RouteReconciliationPeriod = metav1.Duration{Duration: 10 * time.Second} + } +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/doc.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/doc.go new file mode 100644 index 0000000000..91df9c15b1 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/doc.go @@ -0,0 +1,32 @@ +/* +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. +*/ + +// Note: The referenced generic ComponentConfig packages with conversions +// between the types (e.g. the external package) needs to be given as an +// input to conversion-gen for it to find the native conversation funcs to +// call. + +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=k8s.io/component-base/config/v1alpha1 +// +k8s:conversion-gen=k8s.io/cloud-provider/config +// +k8s:conversion-gen=k8s.io/cloud-provider/config/v1alpha1 +// +k8s:conversion-gen=k8s.io/cloud-provider/controllers/service/config/v1alpha1 +// +k8s:conversion-gen=k8s.io/controller-manager/config/v1alpha1 +// +k8s:openapi-gen=true +// +k8s:defaulter-gen=TypeMeta +// +groupName=cloudcontrollermanager.config.k8s.io + +package v1alpha1 // import "k8s.io/cloud-provider/config/v1alpha1" diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/register.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/register.go new file mode 100644 index 0000000000..94320d37c7 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/register.go @@ -0,0 +1,52 @@ +/* +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 v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name use in this package +const GroupName = "cloudcontrollermanager.config.k8s.io" + +var ( + // GroupName is the group name use in this package + SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // localSchemeBuilder ïs a pointer to SchemeBuilder instance. Using localSchemeBuilder + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) + +func init() { + // We only register manually written functions here. The registration of the + // generated functions takes place in the generated files. The separation + // makes the code compile even when the generated files are missing. + localSchemeBuilder.Register(addDefaultingFuncs) +} + +// addKnownTypes registers known types to the given scheme +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &CloudControllerManagerConfiguration{}, + ) + return nil +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/types.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/types.go new file mode 100644 index 0000000000..53689cadc8 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/types.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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + nodeconfigv1alpha1 "k8s.io/cloud-provider/controllers/node/config/v1alpha1" + serviceconfigv1alpha1 "k8s.io/cloud-provider/controllers/service/config/v1alpha1" + cmconfigv1alpha1 "k8s.io/controller-manager/config/v1alpha1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CloudControllerManagerConfiguration contains elements describing cloud-controller manager. +type CloudControllerManagerConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // Generic holds configuration for a generic controller-manager + Generic cmconfigv1alpha1.GenericControllerManagerConfiguration + // KubeCloudSharedConfiguration holds configuration for shared related features + // both in cloud controller manager and kube-controller manager. + KubeCloudShared KubeCloudSharedConfiguration + // NodeController holds configuration for node controller + // related features. + NodeController nodeconfigv1alpha1.NodeControllerConfiguration + // ServiceControllerConfiguration holds configuration for ServiceController + // related features. + ServiceController serviceconfigv1alpha1.ServiceControllerConfiguration + // NodeStatusUpdateFrequency is the frequency at which the controller updates nodes' status + NodeStatusUpdateFrequency metav1.Duration + // Webhook is the configuration for cloud-controller-manager hosted webhooks + Webhook WebhookConfiguration +} + +// KubeCloudSharedConfiguration contains elements shared by both kube-controller manager +// and cloud-controller manager, but not genericconfig. +type KubeCloudSharedConfiguration struct { + // CloudProviderConfiguration holds configuration for CloudProvider related features. + CloudProvider CloudProviderConfiguration + // externalCloudVolumePlugin specifies the plugin to use when cloudProvider is "external". + // It is currently used by the in repo cloud providers to handle node and volume control in the KCM. + ExternalCloudVolumePlugin string + // useServiceAccountCredentials indicates whether controllers should be run with + // individual service account credentials. + UseServiceAccountCredentials bool + // run with untagged cloud instances + AllowUntaggedCloud bool + // routeReconciliationPeriod is the period for reconciling routes created for Nodes by cloud provider.. + RouteReconciliationPeriod metav1.Duration + // nodeMonitorPeriod is the period for syncing NodeStatus in NodeController. + NodeMonitorPeriod metav1.Duration + // clusterName is the instance prefix for the cluster. + ClusterName string + // clusterCIDR is CIDR Range for Pods in cluster. + ClusterCIDR string + // AllocateNodeCIDRs enables CIDRs for Pods to be allocated and, if + // ConfigureCloudRoutes is true, to be set on the cloud provider. + AllocateNodeCIDRs bool + // CIDRAllocatorType determines what kind of pod CIDR allocator will be used. + CIDRAllocatorType string + // configureCloudRoutes enables CIDRs allocated with allocateNodeCIDRs + // to be configured on the cloud provider. + ConfigureCloudRoutes *bool + // nodeSyncPeriod is the period for syncing nodes from cloudprovider. Longer + // periods will result in fewer calls to cloud provider, but may delay addition + // of new nodes to cluster. + NodeSyncPeriod metav1.Duration +} + +// CloudProviderConfiguration contains basically elements about cloud provider. +type CloudProviderConfiguration struct { + // Name is the provider for cloud services. + Name string + // cloudConfigFile is the path to the cloud provider configuration file. + CloudConfigFile string +} + +// WebhookConfiguration contains configuration related to +// cloud-controller-manager hosted webhooks +type WebhookConfiguration struct { + // Webhooks is the list of webhooks to enable or disable + // '*' means "all enabled by default webhooks" + // 'foo' means "enable 'foo'" + // '-foo' means "disable 'foo'" + // first item for a particular name wins + Webhooks []string +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.conversion.go new file mode 100644 index 0000000000..cc8d094149 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.conversion.go @@ -0,0 +1,206 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 conversion-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + unsafe "unsafe" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + config "k8s.io/cloud-provider/config" + nodeconfigv1alpha1 "k8s.io/cloud-provider/controllers/node/config/v1alpha1" + serviceconfigv1alpha1 "k8s.io/cloud-provider/controllers/service/config/v1alpha1" + configv1alpha1 "k8s.io/controller-manager/config/v1alpha1" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*CloudControllerManagerConfiguration)(nil), (*config.CloudControllerManagerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_CloudControllerManagerConfiguration_To_config_CloudControllerManagerConfiguration(a.(*CloudControllerManagerConfiguration), b.(*config.CloudControllerManagerConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.CloudControllerManagerConfiguration)(nil), (*CloudControllerManagerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_CloudControllerManagerConfiguration_To_v1alpha1_CloudControllerManagerConfiguration(a.(*config.CloudControllerManagerConfiguration), b.(*CloudControllerManagerConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*WebhookConfiguration)(nil), (*config.WebhookConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_WebhookConfiguration_To_config_WebhookConfiguration(a.(*WebhookConfiguration), b.(*config.WebhookConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.WebhookConfiguration)(nil), (*WebhookConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_WebhookConfiguration_To_v1alpha1_WebhookConfiguration(a.(*config.WebhookConfiguration), b.(*WebhookConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*config.CloudProviderConfiguration)(nil), (*CloudProviderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_CloudProviderConfiguration_To_v1alpha1_CloudProviderConfiguration(a.(*config.CloudProviderConfiguration), b.(*CloudProviderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*config.KubeCloudSharedConfiguration)(nil), (*KubeCloudSharedConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_KubeCloudSharedConfiguration_To_v1alpha1_KubeCloudSharedConfiguration(a.(*config.KubeCloudSharedConfiguration), b.(*KubeCloudSharedConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*CloudProviderConfiguration)(nil), (*config.CloudProviderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_CloudProviderConfiguration_To_config_CloudProviderConfiguration(a.(*CloudProviderConfiguration), b.(*config.CloudProviderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*KubeCloudSharedConfiguration)(nil), (*config.KubeCloudSharedConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_KubeCloudSharedConfiguration_To_config_KubeCloudSharedConfiguration(a.(*KubeCloudSharedConfiguration), b.(*config.KubeCloudSharedConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_CloudControllerManagerConfiguration_To_config_CloudControllerManagerConfiguration(in *CloudControllerManagerConfiguration, out *config.CloudControllerManagerConfiguration, s conversion.Scope) error { + if err := configv1alpha1.Convert_v1alpha1_GenericControllerManagerConfiguration_To_config_GenericControllerManagerConfiguration(&in.Generic, &out.Generic, s); err != nil { + return err + } + if err := Convert_v1alpha1_KubeCloudSharedConfiguration_To_config_KubeCloudSharedConfiguration(&in.KubeCloudShared, &out.KubeCloudShared, s); err != nil { + return err + } + if err := nodeconfigv1alpha1.Convert_v1alpha1_NodeControllerConfiguration_To_config_NodeControllerConfiguration(&in.NodeController, &out.NodeController, s); err != nil { + return err + } + if err := serviceconfigv1alpha1.Convert_v1alpha1_ServiceControllerConfiguration_To_config_ServiceControllerConfiguration(&in.ServiceController, &out.ServiceController, s); err != nil { + return err + } + out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency + if err := Convert_v1alpha1_WebhookConfiguration_To_config_WebhookConfiguration(&in.Webhook, &out.Webhook, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha1_CloudControllerManagerConfiguration_To_config_CloudControllerManagerConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_CloudControllerManagerConfiguration_To_config_CloudControllerManagerConfiguration(in *CloudControllerManagerConfiguration, out *config.CloudControllerManagerConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_CloudControllerManagerConfiguration_To_config_CloudControllerManagerConfiguration(in, out, s) +} + +func autoConvert_config_CloudControllerManagerConfiguration_To_v1alpha1_CloudControllerManagerConfiguration(in *config.CloudControllerManagerConfiguration, out *CloudControllerManagerConfiguration, s conversion.Scope) error { + if err := configv1alpha1.Convert_config_GenericControllerManagerConfiguration_To_v1alpha1_GenericControllerManagerConfiguration(&in.Generic, &out.Generic, s); err != nil { + return err + } + if err := Convert_config_KubeCloudSharedConfiguration_To_v1alpha1_KubeCloudSharedConfiguration(&in.KubeCloudShared, &out.KubeCloudShared, s); err != nil { + return err + } + if err := nodeconfigv1alpha1.Convert_config_NodeControllerConfiguration_To_v1alpha1_NodeControllerConfiguration(&in.NodeController, &out.NodeController, s); err != nil { + return err + } + if err := serviceconfigv1alpha1.Convert_config_ServiceControllerConfiguration_To_v1alpha1_ServiceControllerConfiguration(&in.ServiceController, &out.ServiceController, s); err != nil { + return err + } + out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency + if err := Convert_config_WebhookConfiguration_To_v1alpha1_WebhookConfiguration(&in.Webhook, &out.Webhook, s); err != nil { + return err + } + return nil +} + +// Convert_config_CloudControllerManagerConfiguration_To_v1alpha1_CloudControllerManagerConfiguration is an autogenerated conversion function. +func Convert_config_CloudControllerManagerConfiguration_To_v1alpha1_CloudControllerManagerConfiguration(in *config.CloudControllerManagerConfiguration, out *CloudControllerManagerConfiguration, s conversion.Scope) error { + return autoConvert_config_CloudControllerManagerConfiguration_To_v1alpha1_CloudControllerManagerConfiguration(in, out, s) +} + +func autoConvert_v1alpha1_CloudProviderConfiguration_To_config_CloudProviderConfiguration(in *CloudProviderConfiguration, out *config.CloudProviderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.CloudConfigFile = in.CloudConfigFile + return nil +} + +func autoConvert_config_CloudProviderConfiguration_To_v1alpha1_CloudProviderConfiguration(in *config.CloudProviderConfiguration, out *CloudProviderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.CloudConfigFile = in.CloudConfigFile + return nil +} + +func autoConvert_v1alpha1_KubeCloudSharedConfiguration_To_config_KubeCloudSharedConfiguration(in *KubeCloudSharedConfiguration, out *config.KubeCloudSharedConfiguration, s conversion.Scope) error { + if err := Convert_v1alpha1_CloudProviderConfiguration_To_config_CloudProviderConfiguration(&in.CloudProvider, &out.CloudProvider, s); err != nil { + return err + } + out.ExternalCloudVolumePlugin = in.ExternalCloudVolumePlugin + out.UseServiceAccountCredentials = in.UseServiceAccountCredentials + out.AllowUntaggedCloud = in.AllowUntaggedCloud + out.RouteReconciliationPeriod = in.RouteReconciliationPeriod + out.NodeMonitorPeriod = in.NodeMonitorPeriod + out.ClusterName = in.ClusterName + out.ClusterCIDR = in.ClusterCIDR + out.AllocateNodeCIDRs = in.AllocateNodeCIDRs + out.CIDRAllocatorType = in.CIDRAllocatorType + if err := v1.Convert_Pointer_bool_To_bool(&in.ConfigureCloudRoutes, &out.ConfigureCloudRoutes, s); err != nil { + return err + } + out.NodeSyncPeriod = in.NodeSyncPeriod + return nil +} + +func autoConvert_config_KubeCloudSharedConfiguration_To_v1alpha1_KubeCloudSharedConfiguration(in *config.KubeCloudSharedConfiguration, out *KubeCloudSharedConfiguration, s conversion.Scope) error { + if err := Convert_config_CloudProviderConfiguration_To_v1alpha1_CloudProviderConfiguration(&in.CloudProvider, &out.CloudProvider, s); err != nil { + return err + } + out.ExternalCloudVolumePlugin = in.ExternalCloudVolumePlugin + out.UseServiceAccountCredentials = in.UseServiceAccountCredentials + out.AllowUntaggedCloud = in.AllowUntaggedCloud + out.RouteReconciliationPeriod = in.RouteReconciliationPeriod + out.NodeMonitorPeriod = in.NodeMonitorPeriod + out.ClusterName = in.ClusterName + out.ClusterCIDR = in.ClusterCIDR + out.AllocateNodeCIDRs = in.AllocateNodeCIDRs + out.CIDRAllocatorType = in.CIDRAllocatorType + if err := v1.Convert_bool_To_Pointer_bool(&in.ConfigureCloudRoutes, &out.ConfigureCloudRoutes, s); err != nil { + return err + } + out.NodeSyncPeriod = in.NodeSyncPeriod + return nil +} + +func autoConvert_v1alpha1_WebhookConfiguration_To_config_WebhookConfiguration(in *WebhookConfiguration, out *config.WebhookConfiguration, s conversion.Scope) error { + out.Webhooks = *(*[]string)(unsafe.Pointer(&in.Webhooks)) + return nil +} + +// Convert_v1alpha1_WebhookConfiguration_To_config_WebhookConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_WebhookConfiguration_To_config_WebhookConfiguration(in *WebhookConfiguration, out *config.WebhookConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_WebhookConfiguration_To_config_WebhookConfiguration(in, out, s) +} + +func autoConvert_config_WebhookConfiguration_To_v1alpha1_WebhookConfiguration(in *config.WebhookConfiguration, out *WebhookConfiguration, s conversion.Scope) error { + out.Webhooks = *(*[]string)(unsafe.Pointer(&in.Webhooks)) + return nil +} + +// Convert_config_WebhookConfiguration_To_v1alpha1_WebhookConfiguration is an autogenerated conversion function. +func Convert_config_WebhookConfiguration_To_v1alpha1_WebhookConfiguration(in *config.WebhookConfiguration, out *WebhookConfiguration, s conversion.Scope) error { + return autoConvert_config_WebhookConfiguration_To_v1alpha1_WebhookConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..40a61f147c --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,119 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +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 *CloudControllerManagerConfiguration) DeepCopyInto(out *CloudControllerManagerConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + in.Generic.DeepCopyInto(&out.Generic) + in.KubeCloudShared.DeepCopyInto(&out.KubeCloudShared) + out.NodeController = in.NodeController + out.ServiceController = in.ServiceController + out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency + in.Webhook.DeepCopyInto(&out.Webhook) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudControllerManagerConfiguration. +func (in *CloudControllerManagerConfiguration) DeepCopy() *CloudControllerManagerConfiguration { + if in == nil { + return nil + } + out := new(CloudControllerManagerConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CloudControllerManagerConfiguration) 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 *CloudProviderConfiguration) DeepCopyInto(out *CloudProviderConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudProviderConfiguration. +func (in *CloudProviderConfiguration) DeepCopy() *CloudProviderConfiguration { + if in == nil { + return nil + } + out := new(CloudProviderConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeCloudSharedConfiguration) DeepCopyInto(out *KubeCloudSharedConfiguration) { + *out = *in + out.CloudProvider = in.CloudProvider + out.RouteReconciliationPeriod = in.RouteReconciliationPeriod + out.NodeMonitorPeriod = in.NodeMonitorPeriod + if in.ConfigureCloudRoutes != nil { + in, out := &in.ConfigureCloudRoutes, &out.ConfigureCloudRoutes + *out = new(bool) + **out = **in + } + out.NodeSyncPeriod = in.NodeSyncPeriod + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeCloudSharedConfiguration. +func (in *KubeCloudSharedConfiguration) DeepCopy() *KubeCloudSharedConfiguration { + if in == nil { + return nil + } + out := new(KubeCloudSharedConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WebhookConfiguration) DeepCopyInto(out *WebhookConfiguration) { + *out = *in + if in.Webhooks != nil { + in, out := &in.Webhooks, &out.Webhooks + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookConfiguration. +func (in *WebhookConfiguration) DeepCopy() *WebhookConfiguration { + if in == nil { + return nil + } + out := new(WebhookConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.defaults.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.defaults.go new file mode 100644 index 0000000000..96b18ded97 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.defaults.go @@ -0,0 +1,41 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 defaulter-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// RegisterDefaults adds defaulters functions to the given scheme. +// Public to allow building arbitrary schemes. +// All generated defaulters are covering - they call all nested defaulters. +func RegisterDefaults(scheme *runtime.Scheme) error { + scheme.AddTypeDefaultingFunc(&CloudControllerManagerConfiguration{}, func(obj interface{}) { + SetObjectDefaults_CloudControllerManagerConfiguration(obj.(*CloudControllerManagerConfiguration)) + }) + return nil +} + +func SetObjectDefaults_CloudControllerManagerConfiguration(in *CloudControllerManagerConfiguration) { + SetDefaults_CloudControllerManagerConfiguration(in) + SetDefaults_KubeCloudSharedConfiguration(&in.KubeCloudShared) +} diff --git a/vendor/k8s.io/cloud-provider/config/zz_generated.deepcopy.go b/vendor/k8s.io/cloud-provider/config/zz_generated.deepcopy.go new file mode 100644 index 0000000000..8225daba1a --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/zz_generated.deepcopy.go @@ -0,0 +1,114 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 deepcopy-gen. DO NOT EDIT. + +package config + +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 *CloudControllerManagerConfiguration) DeepCopyInto(out *CloudControllerManagerConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + in.Generic.DeepCopyInto(&out.Generic) + out.KubeCloudShared = in.KubeCloudShared + out.NodeController = in.NodeController + out.ServiceController = in.ServiceController + out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency + in.Webhook.DeepCopyInto(&out.Webhook) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudControllerManagerConfiguration. +func (in *CloudControllerManagerConfiguration) DeepCopy() *CloudControllerManagerConfiguration { + if in == nil { + return nil + } + out := new(CloudControllerManagerConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CloudControllerManagerConfiguration) 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 *CloudProviderConfiguration) DeepCopyInto(out *CloudProviderConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudProviderConfiguration. +func (in *CloudProviderConfiguration) DeepCopy() *CloudProviderConfiguration { + if in == nil { + return nil + } + out := new(CloudProviderConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeCloudSharedConfiguration) DeepCopyInto(out *KubeCloudSharedConfiguration) { + *out = *in + out.CloudProvider = in.CloudProvider + out.RouteReconciliationPeriod = in.RouteReconciliationPeriod + out.NodeMonitorPeriod = in.NodeMonitorPeriod + out.NodeSyncPeriod = in.NodeSyncPeriod + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeCloudSharedConfiguration. +func (in *KubeCloudSharedConfiguration) DeepCopy() *KubeCloudSharedConfiguration { + if in == nil { + return nil + } + out := new(KubeCloudSharedConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WebhookConfiguration) DeepCopyInto(out *WebhookConfiguration) { + *out = *in + if in.Webhooks != nil { + in, out := &in.Webhooks, &out.Webhooks + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookConfiguration. +func (in *WebhookConfiguration) DeepCopy() *WebhookConfiguration { + if in == nil { + return nil + } + out := new(WebhookConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/types.go b/vendor/k8s.io/cloud-provider/controllers/node/config/types.go new file mode 100644 index 0000000000..af7c788035 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/types.go @@ -0,0 +1,24 @@ +/* +Copyright 2022 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 config + +// NodeControllerConfiguration contains elements describing NodeController. +type NodeControllerConfiguration struct { + // ConcurrentNodeSyncs is the number of workers + // concurrently synchronizing nodes + ConcurrentNodeSyncs int32 +} diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/conversion.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/conversion.go new file mode 100644 index 0000000000..07dc75d31c --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/conversion.go @@ -0,0 +1,39 @@ +/* +Copyright 2022 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 v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/conversion" + "k8s.io/cloud-provider/controllers/node/config" +) + +// Important! The public back-and-forth conversion functions for the types in this generic +// package with ComponentConfig types need to be manually exposed like this in order for +// other packages that reference this package to be able to call these conversion functions +// in an autogenerated manner. +// TODO: Fix the bug in conversion-gen so it automatically discovers these Convert_* functions +// in autogenerated code as well. + +// Convert_config_NodeControllerConfiguration_To_v1alpha1_NodeControllerConfiguration is an autogenerated conversion function. +func Convert_config_NodeControllerConfiguration_To_v1alpha1_NodeControllerConfiguration(in *config.NodeControllerConfiguration, out *NodeControllerConfiguration, s conversion.Scope) error { + return autoConvert_config_NodeControllerConfiguration_To_v1alpha1_NodeControllerConfiguration(in, out, s) +} + +// Convert_v1alpha1_NodeControllerConfiguration_To_config_NodeControllerConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_NodeControllerConfiguration_To_config_NodeControllerConfiguration(in *NodeControllerConfiguration, out *config.NodeControllerConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_NodeControllerConfiguration_To_config_NodeControllerConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/defaults.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/defaults.go new file mode 100644 index 0000000000..5f5ff95ff1 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/defaults.go @@ -0,0 +1,23 @@ +/* +Copyright 2022 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 v1alpha1 + +func RecommendedDefaultNodeControllerConfiguration(obj *NodeControllerConfiguration) { + if obj.ConcurrentNodeSyncs == 0 { + obj.ConcurrentNodeSyncs = 1 + } +} diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/doc.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/doc.go new file mode 100644 index 0000000000..eff177166e --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2022 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. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=k8s.io/cloud-provider/controllers/node/config +// +k8s:conversion-gen=k8s.io/cloud-provider/controllers/node/config/v1alpha1 + +package v1alpha1 // import "k8s.io/cloud-provider/controllers/node/config/v1alpha1" diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/register.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/register.go new file mode 100644 index 0000000000..a25accd070 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/register.go @@ -0,0 +1,31 @@ +/* +Copyright 2022 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 v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" +) + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder runtime.SchemeBuilder + // localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package, + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/types.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/types.go new file mode 100644 index 0000000000..ca85a557cb --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/types.go @@ -0,0 +1,24 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +// NodeControllerConfiguration contains elements describing NodeController. +type NodeControllerConfiguration struct { + // ConcurrentNodeSyncs is the number of workers + // concurrently synchronizing nodes + ConcurrentNodeSyncs int32 +} diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.conversion.go new file mode 100644 index 0000000000..cf3852db29 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.conversion.go @@ -0,0 +1,58 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 conversion-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + config "k8s.io/cloud-provider/controllers/node/config" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddConversionFunc((*config.NodeControllerConfiguration)(nil), (*NodeControllerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_NodeControllerConfiguration_To_v1alpha1_NodeControllerConfiguration(a.(*config.NodeControllerConfiguration), b.(*NodeControllerConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*NodeControllerConfiguration)(nil), (*config.NodeControllerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_NodeControllerConfiguration_To_config_NodeControllerConfiguration(a.(*NodeControllerConfiguration), b.(*config.NodeControllerConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_NodeControllerConfiguration_To_config_NodeControllerConfiguration(in *NodeControllerConfiguration, out *config.NodeControllerConfiguration, s conversion.Scope) error { + out.ConcurrentNodeSyncs = in.ConcurrentNodeSyncs + return nil +} + +func autoConvert_config_NodeControllerConfiguration_To_v1alpha1_NodeControllerConfiguration(in *config.NodeControllerConfiguration, out *NodeControllerConfiguration, s conversion.Scope) error { + out.ConcurrentNodeSyncs = in.ConcurrentNodeSyncs + return nil +} diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..7e7c1b9fad --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,38 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeControllerConfiguration) DeepCopyInto(out *NodeControllerConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeControllerConfiguration. +func (in *NodeControllerConfiguration) DeepCopy() *NodeControllerConfiguration { + if in == nil { + return nil + } + out := new(NodeControllerConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/OWNERS b/vendor/k8s.io/cloud-provider/controllers/service/config/OWNERS new file mode 100644 index 0000000000..200d01f74c --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/OWNERS @@ -0,0 +1,14 @@ +approvers: + - api-approvers + - deads2k + - luxas + - mtaufen + - sttts +reviewers: + - api-reviewers + - deads2k + - luxas + - mtaufen + - sttts +emeritus_approvers: + - stewart-yu diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/doc.go b/vendor/k8s.io/cloud-provider/controllers/service/config/doc.go new file mode 100644 index 0000000000..4c3d3aae1e --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package + +package config // import "k8s.io/cloud-provider/controllers/service/config" diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/types.go b/vendor/k8s.io/cloud-provider/controllers/service/config/types.go new file mode 100644 index 0000000000..3afca16300 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/types.go @@ -0,0 +1,25 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config + +// ServiceControllerConfiguration contains elements describing ServiceController. +type ServiceControllerConfiguration struct { + // concurrentServiceSyncs is the number of services that are + // allowed to sync concurrently. Larger number = more responsive service + // management, but more CPU (and network) load. + ConcurrentServiceSyncs int32 +} diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/conversion.go b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/conversion.go new file mode 100644 index 0000000000..1c9ccc641a --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/conversion.go @@ -0,0 +1,39 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/conversion" + serviceconfig "k8s.io/cloud-provider/controllers/service/config" +) + +// Important! The public back-and-forth conversion functions for the types in this generic +// package with ComponentConfig types need to be manually exposed like this in order for +// other packages that reference this package to be able to call these conversion functions +// in an autogenerated manner. +// TODO: Fix the bug in conversion-gen so it automatically discovers these Convert_* functions +// in autogenerated code as well. + +// Convert_v1alpha1_ServiceControllerConfiguration_To_config_ServiceControllerConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_ServiceControllerConfiguration_To_config_ServiceControllerConfiguration(in *ServiceControllerConfiguration, out *serviceconfig.ServiceControllerConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_ServiceControllerConfiguration_To_config_ServiceControllerConfiguration(in, out, s) +} + +// Convert_config_ServiceControllerConfiguration_To_v1alpha1_ServiceControllerConfiguration is an autogenerated conversion function. +func Convert_config_ServiceControllerConfiguration_To_v1alpha1_ServiceControllerConfiguration(in *serviceconfig.ServiceControllerConfiguration, out *ServiceControllerConfiguration, s conversion.Scope) error { + return autoConvert_config_ServiceControllerConfiguration_To_v1alpha1_ServiceControllerConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/defaults.go b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/defaults.go new file mode 100644 index 0000000000..e4a8edb9e3 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/defaults.go @@ -0,0 +1,32 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +// RecommendedDefaultServiceControllerConfiguration defaults a pointer to a +// ServiceControllerConfiguration struct. This will set the recommended default +// values, but they may be subject to change between API versions. This function +// is intentionally not registered in the scheme as a "normal" `SetDefaults_Foo` +// function to allow consumers of this type to set whatever defaults for their +// embedded configs. Forcing consumers to use these defaults would be problematic +// as defaulting in the scheme is done as part of the conversion, and there would +// be no easy way to opt-out. Instead, if you want to use this defaulting method +// run it in your wrapper struct of this type in its `SetDefaults_` method. +func RecommendedDefaultServiceControllerConfiguration(obj *ServiceControllerConfiguration) { + if obj.ConcurrentServiceSyncs == 0 { + obj.ConcurrentServiceSyncs = 1 + } +} diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/doc.go b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/doc.go new file mode 100644 index 0000000000..3d71af8aff --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=k8s.io/cloud-provider/controllers/service/config +// +k8s:conversion-gen=k8s.io/cloud-provider/controllers/service/config/v1alpha1 + +package v1alpha1 // import "k8s.io/cloud-provider/controllers/service/config/v1alpha1" diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/register.go b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/register.go new file mode 100644 index 0000000000..47e0707822 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/register.go @@ -0,0 +1,31 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" +) + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder runtime.SchemeBuilder + // localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package, + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/types.go b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/types.go new file mode 100644 index 0000000000..10ab1d2d9c --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/types.go @@ -0,0 +1,25 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +// ServiceControllerConfiguration contains elements describing ServiceController. +type ServiceControllerConfiguration struct { + // concurrentServiceSyncs is the number of services that are + // allowed to sync concurrently. Larger number = more responsive service + // management, but more CPU (and network) load. + ConcurrentServiceSyncs int32 +} diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/zz_generated.conversion.go new file mode 100644 index 0000000000..5c4e7db7a8 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/zz_generated.conversion.go @@ -0,0 +1,58 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 conversion-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + config "k8s.io/cloud-provider/controllers/service/config" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddConversionFunc((*config.ServiceControllerConfiguration)(nil), (*ServiceControllerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_ServiceControllerConfiguration_To_v1alpha1_ServiceControllerConfiguration(a.(*config.ServiceControllerConfiguration), b.(*ServiceControllerConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*ServiceControllerConfiguration)(nil), (*config.ServiceControllerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ServiceControllerConfiguration_To_config_ServiceControllerConfiguration(a.(*ServiceControllerConfiguration), b.(*config.ServiceControllerConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_ServiceControllerConfiguration_To_config_ServiceControllerConfiguration(in *ServiceControllerConfiguration, out *config.ServiceControllerConfiguration, s conversion.Scope) error { + out.ConcurrentServiceSyncs = in.ConcurrentServiceSyncs + return nil +} + +func autoConvert_config_ServiceControllerConfiguration_To_v1alpha1_ServiceControllerConfiguration(in *config.ServiceControllerConfiguration, out *ServiceControllerConfiguration, s conversion.Scope) error { + out.ConcurrentServiceSyncs = in.ConcurrentServiceSyncs + return nil +} diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..49a9f7d2aa --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,38 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceControllerConfiguration) DeepCopyInto(out *ServiceControllerConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceControllerConfiguration. +func (in *ServiceControllerConfiguration) DeepCopy() *ServiceControllerConfiguration { + if in == nil { + return nil + } + out := new(ServiceControllerConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/zz_generated.deepcopy.go b/vendor/k8s.io/cloud-provider/controllers/service/config/zz_generated.deepcopy.go new file mode 100644 index 0000000000..53eb242968 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/zz_generated.deepcopy.go @@ -0,0 +1,38 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 deepcopy-gen. DO NOT EDIT. + +package config + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceControllerConfiguration) DeepCopyInto(out *ServiceControllerConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceControllerConfiguration. +func (in *ServiceControllerConfiguration) DeepCopy() *ServiceControllerConfiguration { + if in == nil { + return nil + } + out := new(ServiceControllerConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/cloud-provider/node/helpers/address.go b/vendor/k8s.io/cloud-provider/node/helpers/address.go index 6eb44a90fe..41112cdaeb 100644 --- a/vendor/k8s.io/cloud-provider/node/helpers/address.go +++ b/vendor/k8s.io/cloud-provider/node/helpers/address.go @@ -21,6 +21,7 @@ import ( "net" "k8s.io/api/core/v1" + nodeutil "k8s.io/component-helpers/node/util" netutils "k8s.io/utils/net" ) @@ -41,8 +42,8 @@ func AddToNodeAddresses(addresses *[]v1.NodeAddress, addAddresses ...v1.NodeAddr } } -// PreferNodeIP filters node addresses to prefer a specific node IP or address -// family. +// GetNodeAddressesFromNodeIPLegacy filters node addresses to prefer a specific node IP or +// address family. This function is used only with legacy cloud providers. // // If nodeIP is either '0.0.0.0' or '::' it is taken to represent any address of // that address family: IPv4 or IPv6. i.e. if nodeIP is '0.0.0.0' we will return @@ -55,7 +56,7 @@ func AddToNodeAddresses(addresses *[]v1.NodeAddress, addAddresses ...v1.NodeAddr // - If nodeIP matches an address of a particular type (internal or external), // that will be the *only* address of that type returned. // - All remaining addresses are listed after. -func PreferNodeIP(nodeIP net.IP, cloudNodeAddresses []v1.NodeAddress) ([]v1.NodeAddress, error) { +func GetNodeAddressesFromNodeIPLegacy(nodeIP net.IP, cloudNodeAddresses []v1.NodeAddress) ([]v1.NodeAddress, error) { // If nodeIP is unset, just use the addresses provided by the cloud provider as-is if nodeIP == nil { return cloudNodeAddresses, nil @@ -83,26 +84,58 @@ func PreferNodeIP(nodeIP net.IP, cloudNodeAddresses []v1.NodeAddress) ([]v1.Node return sortedAddresses, nil } - // For every address supplied by the cloud provider that matches nodeIP, nodeIP is the enforced node address for - // that address Type (like InternalIP and ExternalIP), meaning other addresses of the same Type are discarded. - // See #61921 for more information: some cloud providers may supply secondary IPs, so nodeIP serves as a way to - // ensure that the correct IPs show up on a Node object. - enforcedNodeAddresses := []v1.NodeAddress{} + // Otherwise the result is the same as for GetNodeAddressesFromNodeIP + return GetNodeAddressesFromNodeIP(nodeIP.String(), cloudNodeAddresses, false) +} + +// GetNodeAddressesFromNodeIP filters the provided list of nodeAddresses to match the +// providedNodeIP from the Node annotation (which is assumed to be non-empty). This is +// used for external cloud providers. +// +// It will return node addresses filtered such that: +// - Any address matching nodeIP will be listed first. +// - If nodeIP matches an address of a particular type (internal or external), +// that will be the *only* address of that type returned. +// - All remaining addresses are listed after. +// +// (This does not have the same behavior with `0.0.0.0` and `::` as +// GetNodeAddressesFromNodeIPLegacy, because that case never occurs for external cloud +// providers, because kubelet does not set the `provided-node-ip` annotation in that +// case.) +func GetNodeAddressesFromNodeIP(providedNodeIP string, cloudNodeAddresses []v1.NodeAddress, allowDualStack bool) ([]v1.NodeAddress, error) { + nodeIPs, err := nodeutil.ParseNodeIPAnnotation(providedNodeIP, allowDualStack) + if err != nil { + return nil, fmt.Errorf("failed to parse node IP %q: %v", providedNodeIP, err) + } + enforcedNodeAddresses := []v1.NodeAddress{} nodeIPTypes := make(map[v1.NodeAddressType]bool) - for _, nodeAddress := range cloudNodeAddresses { - if netutils.ParseIPSloppy(nodeAddress.Address).Equal(nodeIP) { - enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: nodeAddress.Type, Address: nodeAddress.Address}) - nodeIPTypes[nodeAddress.Type] = true + + for _, nodeIP := range nodeIPs { + // For every address supplied by the cloud provider that matches nodeIP, + // nodeIP is the enforced node address for that address Type (like + // InternalIP and ExternalIP), meaning other addresses of the same Type + // are discarded. See #61921 for more information: some cloud providers + // may supply secondary IPs, so nodeIP serves as a way to ensure that the + // correct IPs show up on a Node object. + + matched := false + for _, nodeAddress := range cloudNodeAddresses { + if netutils.ParseIPSloppy(nodeAddress.Address).Equal(nodeIP) { + enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: nodeAddress.Type, Address: nodeAddress.Address}) + nodeIPTypes[nodeAddress.Type] = true + matched = true + } } - } - // nodeIP must be among the addresses supplied by the cloud provider - if len(enforcedNodeAddresses) == 0 { - return nil, fmt.Errorf("failed to get node address from cloud provider that matches ip: %v", nodeIP) + // nodeIP must be among the addresses supplied by the cloud provider + if !matched { + return nil, fmt.Errorf("failed to get node address from cloud provider that matches ip: %v", nodeIP) + } } - // nodeIP was found, now use all other addresses supplied by the cloud provider NOT of the same Type as nodeIP. + // Now use all other addresses supplied by the cloud provider NOT of the same Type + // as any nodeIP. for _, nodeAddress := range cloudNodeAddresses { if !nodeIPTypes[nodeAddress.Type] { enforcedNodeAddresses = append(enforcedNodeAddresses, v1.NodeAddress{Type: nodeAddress.Type, Address: nodeAddress.Address}) diff --git a/vendor/k8s.io/cloud-provider/options/cloudprovider.go b/vendor/k8s.io/cloud-provider/options/cloudprovider.go new file mode 100644 index 0000000000..6b5034abab --- /dev/null +++ b/vendor/k8s.io/cloud-provider/options/cloudprovider.go @@ -0,0 +1,54 @@ +/* +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 + +import ( + "github.com/spf13/pflag" + cpconfig "k8s.io/cloud-provider/config" +) + +// CloudProviderOptions holds the cloudprovider options. +type CloudProviderOptions struct { + *cpconfig.CloudProviderConfiguration +} + +// Validate checks validation of cloudprovider options. +func (s *CloudProviderOptions) Validate() []error { + allErrors := []error{} + return allErrors +} + +// AddFlags adds flags related to cloudprovider for controller manager to the specified FlagSet. +func (s *CloudProviderOptions) AddFlags(fs *pflag.FlagSet) { + fs.StringVar(&s.Name, "cloud-provider", s.Name, + "The provider for cloud services. Empty string for no provider.") + + fs.StringVar(&s.CloudConfigFile, "cloud-config", s.CloudConfigFile, + "The path to the cloud provider configuration file. Empty string for no configuration file.") +} + +// ApplyTo fills up cloudprovider config with options. +func (s *CloudProviderOptions) ApplyTo(cfg *cpconfig.CloudProviderConfiguration) error { + if s == nil { + return nil + } + + cfg.Name = s.Name + cfg.CloudConfigFile = s.CloudConfigFile + + return nil +} diff --git a/vendor/k8s.io/cloud-provider/options/kubecloudshared.go b/vendor/k8s.io/cloud-provider/options/kubecloudshared.go new file mode 100644 index 0000000000..20bb03c095 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/options/kubecloudshared.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 options + +import ( + "github.com/spf13/pflag" + cpconfig "k8s.io/cloud-provider/config" +) + +// KubeCloudSharedOptions holds the options shared between kube-controller-manager +// and cloud-controller-manager. +type KubeCloudSharedOptions struct { + *cpconfig.KubeCloudSharedConfiguration + CloudProvider *CloudProviderOptions +} + +// NewKubeCloudSharedOptions returns common/default configuration values for both +// the kube-controller-manager and the cloud-contoller-manager. Any common changes should +// be made here. Any individual changes should be made in that controller. +func NewKubeCloudSharedOptions(cfg *cpconfig.KubeCloudSharedConfiguration) *KubeCloudSharedOptions { + o := &KubeCloudSharedOptions{ + KubeCloudSharedConfiguration: cfg, + CloudProvider: &CloudProviderOptions{ + CloudProviderConfiguration: &cpconfig.CloudProviderConfiguration{}, + }, + } + + return o +} + +// AddFlags adds flags related to shared variable for controller manager to the specified FlagSet. +func (o *KubeCloudSharedOptions) AddFlags(fs *pflag.FlagSet) { + if o == nil { + return + } + + o.CloudProvider.AddFlags(fs) + fs.StringVar(&o.ExternalCloudVolumePlugin, "external-cloud-volume-plugin", o.ExternalCloudVolumePlugin, "The plugin to use when cloud provider is set to external. Can be empty, should only be set when cloud-provider is external. Currently used to allow node and volume controllers to work for in tree cloud providers.") + fs.BoolVar(&o.UseServiceAccountCredentials, "use-service-account-credentials", o.UseServiceAccountCredentials, "If true, use individual service account credentials for each controller.") + fs.BoolVar(&o.AllowUntaggedCloud, "allow-untagged-cloud", false, "Allow the cluster to run without the cluster-id on cloud instances. This is a legacy mode of operation and a cluster-id will be required in the future.") + fs.MarkDeprecated("allow-untagged-cloud", "This flag is deprecated and will be removed in a future release. A cluster-id will be required on cloud instances.") + fs.DurationVar(&o.RouteReconciliationPeriod.Duration, "route-reconciliation-period", o.RouteReconciliationPeriod.Duration, "The period for reconciling routes created for Nodes by cloud provider.") + fs.DurationVar(&o.NodeMonitorPeriod.Duration, "node-monitor-period", o.NodeMonitorPeriod.Duration, + "The period for syncing NodeStatus in NodeController.") + fs.StringVar(&o.ClusterName, "cluster-name", o.ClusterName, "The instance prefix for the cluster.") + fs.StringVar(&o.ClusterCIDR, "cluster-cidr", o.ClusterCIDR, "CIDR Range for Pods in cluster. Requires --allocate-node-cidrs to be true") + fs.BoolVar(&o.AllocateNodeCIDRs, "allocate-node-cidrs", false, "Should CIDRs for Pods be allocated and set on the cloud provider.") + fs.StringVar(&o.CIDRAllocatorType, "cidr-allocator-type", "RangeAllocator", "Type of CIDR allocator to use") + fs.BoolVar(&o.ConfigureCloudRoutes, "configure-cloud-routes", true, "Should CIDRs allocated by allocate-node-cidrs be configured on the cloud provider.") + + fs.DurationVar(&o.NodeSyncPeriod.Duration, "node-sync-period", 0, ""+ + "This flag is deprecated and will be removed in future releases. See node-monitor-period for Node health checking or "+ + "route-reconciliation-period for cloud provider's route configuration settings.") + fs.MarkDeprecated("node-sync-period", "This flag is currently no-op and will be deleted.") +} + +// ApplyTo fills up KubeCloudShared config with options. +func (o *KubeCloudSharedOptions) ApplyTo(cfg *cpconfig.KubeCloudSharedConfiguration) error { + if o == nil { + return nil + } + + if err := o.CloudProvider.ApplyTo(&cfg.CloudProvider); err != nil { + return err + } + + cfg.ExternalCloudVolumePlugin = o.ExternalCloudVolumePlugin + cfg.UseServiceAccountCredentials = o.UseServiceAccountCredentials + cfg.AllowUntaggedCloud = o.AllowUntaggedCloud + cfg.RouteReconciliationPeriod = o.RouteReconciliationPeriod + cfg.NodeMonitorPeriod = o.NodeMonitorPeriod + cfg.ClusterName = o.ClusterName + cfg.ClusterCIDR = o.ClusterCIDR + cfg.AllocateNodeCIDRs = o.AllocateNodeCIDRs + cfg.CIDRAllocatorType = o.CIDRAllocatorType + cfg.ConfigureCloudRoutes = o.ConfigureCloudRoutes + cfg.NodeSyncPeriod = o.NodeSyncPeriod + + return nil +} + +// Validate checks validation of KubeCloudSharedOptions. +func (o *KubeCloudSharedOptions) Validate() []error { + if o == nil { + return nil + } + + errs := []error{} + errs = append(errs, o.CloudProvider.Validate()...) + + return errs +} diff --git a/vendor/k8s.io/cloud-provider/options/nodecontroller.go b/vendor/k8s.io/cloud-provider/options/nodecontroller.go new file mode 100644 index 0000000000..4823c437b1 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/options/nodecontroller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package options + +import ( + "fmt" + + "github.com/spf13/pflag" + + nodeconfig "k8s.io/cloud-provider/controllers/node/config" +) + +// NodeControllerOptions holds the ServiceController options. +type NodeControllerOptions struct { + *nodeconfig.NodeControllerConfiguration +} + +// AddFlags adds flags related to ServiceController for controller manager to the specified FlagSet. +func (o *NodeControllerOptions) AddFlags(fs *pflag.FlagSet) { + if o == nil { + return + } + + fs.Int32Var(&o.ConcurrentNodeSyncs, "concurrent-node-syncs", o.ConcurrentNodeSyncs, "Number of workers concurrently synchronizing nodes.") +} + +// ApplyTo fills up ServiceController config with options. +func (o *NodeControllerOptions) ApplyTo(cfg *nodeconfig.NodeControllerConfiguration) error { + if o == nil { + return nil + } + + cfg.ConcurrentNodeSyncs = o.ConcurrentNodeSyncs + + return nil +} + +// Validate checks validation of NodeControllerOptions. +func (o *NodeControllerOptions) Validate() []error { + if o == nil { + return nil + } + var errors []error + if o.ConcurrentNodeSyncs <= 0 { + errors = append(errors, fmt.Errorf("concurrent-node-syncs must be a positive number")) + } + return errors +} diff --git a/vendor/k8s.io/cloud-provider/options/options.go b/vendor/k8s.io/cloud-provider/options/options.go new file mode 100644 index 0000000000..35bf1737ed --- /dev/null +++ b/vendor/k8s.io/cloud-provider/options/options.go @@ -0,0 +1,306 @@ +/* +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 options + +import ( + "fmt" + "math/rand" + "net" + "time" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + apiserveroptions "k8s.io/apiserver/pkg/server/options" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/client-go/informers" + clientset "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/tools/record" + cloudprovider "k8s.io/cloud-provider" + "k8s.io/cloud-provider/app/config" + ccmconfig "k8s.io/cloud-provider/config" + ccmconfigscheme "k8s.io/cloud-provider/config/install" + ccmconfigv1alpha1 "k8s.io/cloud-provider/config/v1alpha1" + cliflag "k8s.io/component-base/cli/flag" + cmoptions "k8s.io/controller-manager/options" + "k8s.io/controller-manager/pkg/clientbuilder" + netutils "k8s.io/utils/net" + + // add the related feature gates + _ "k8s.io/controller-manager/pkg/features/register" +) + +const ( + // CloudControllerManagerUserAgent is the userAgent name when starting cloud-controller managers. + CloudControllerManagerUserAgent = "cloud-controller-manager" +) + +// CloudControllerManagerOptions is the main context object for the controller manager. +type CloudControllerManagerOptions struct { + Generic *cmoptions.GenericControllerManagerConfigurationOptions + KubeCloudShared *KubeCloudSharedOptions + ServiceController *ServiceControllerOptions + NodeController *NodeControllerOptions + + SecureServing *apiserveroptions.SecureServingOptionsWithLoopback + Authentication *apiserveroptions.DelegatingAuthenticationOptions + Authorization *apiserveroptions.DelegatingAuthorizationOptions + + Master string + + WebhookServing *WebhookServingOptions + Webhook *WebhookOptions + + // NodeStatusUpdateFrequency is the frequency at which the controller updates nodes' status + NodeStatusUpdateFrequency metav1.Duration +} + +// ProviderDefaults are provided by the consumer when calling +// NewCloudControllerManagerOptions(), so that they can customize certain flag +// default values. +type ProviderDefaults struct { + // WebhookBindAddress is the default address. It can be overridden by "--webhook-bind-address". + WebhookBindAddress *net.IP + // WebhookBindPort is the default port. It can be overridden by "--webhook-bind-port". + WebhookBindPort *int +} + +// NewCloudControllerManagerOptions creates a new ExternalCMServer with a default config. +func NewCloudControllerManagerOptions() (*CloudControllerManagerOptions, error) { + return NewCloudControllerManagerOptionsWithProviderDefaults(ProviderDefaults{}) +} + +// NewCloudControllerManagerOptionsWithProviderDefaults creates a new +// ExternalCMServer with a default config, but allows the cloud provider to +// override a select number of default option values. +func NewCloudControllerManagerOptionsWithProviderDefaults(defaults ProviderDefaults) (*CloudControllerManagerOptions, error) { + componentConfig, err := NewDefaultComponentConfig() + if err != nil { + return nil, err + } + + s := CloudControllerManagerOptions{ + Generic: cmoptions.NewGenericControllerManagerConfigurationOptions(&componentConfig.Generic), + KubeCloudShared: NewKubeCloudSharedOptions(&componentConfig.KubeCloudShared), + NodeController: &NodeControllerOptions{ + NodeControllerConfiguration: &componentConfig.NodeController, + }, + ServiceController: &ServiceControllerOptions{ + ServiceControllerConfiguration: &componentConfig.ServiceController, + }, + SecureServing: apiserveroptions.NewSecureServingOptions().WithLoopback(), + Webhook: NewWebhookOptions(), + WebhookServing: NewWebhookServingOptions(defaults), + Authentication: apiserveroptions.NewDelegatingAuthenticationOptions(), + Authorization: apiserveroptions.NewDelegatingAuthorizationOptions(), + NodeStatusUpdateFrequency: componentConfig.NodeStatusUpdateFrequency, + } + + s.Authentication.RemoteKubeConfigFileOptional = true + s.Authorization.RemoteKubeConfigFileOptional = true + + // 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 = cloudprovider.CloudControllerManagerPort + + s.Generic.LeaderElection.ResourceName = "cloud-controller-manager" + s.Generic.LeaderElection.ResourceNamespace = "kube-system" + + return &s, nil +} + +// NewDefaultComponentConfig returns cloud-controller manager configuration object. +func NewDefaultComponentConfig() (*ccmconfig.CloudControllerManagerConfiguration, error) { + versioned := &ccmconfigv1alpha1.CloudControllerManagerConfiguration{} + ccmconfigscheme.Scheme.Default(versioned) + + internal := &ccmconfig.CloudControllerManagerConfiguration{} + if err := ccmconfigscheme.Scheme.Convert(versioned, internal, nil); err != nil { + return nil, err + } + + return internal, nil +} + +// Flags returns flags for a specific CloudController by section name +func (o *CloudControllerManagerOptions) Flags(allControllers, disabledByDefaultControllers, allWebhooks, disabledByDefaultWebhooks []string) cliflag.NamedFlagSets { + fss := cliflag.NamedFlagSets{} + o.Generic.AddFlags(&fss, allControllers, disabledByDefaultControllers) + o.KubeCloudShared.AddFlags(fss.FlagSet("generic")) + o.NodeController.AddFlags(fss.FlagSet("node controller")) + o.ServiceController.AddFlags(fss.FlagSet("service controller")) + if o.Webhook != nil { + o.Webhook.AddFlags(fss.FlagSet("webhook"), allWebhooks, disabledByDefaultWebhooks) + } + if o.WebhookServing != nil { + o.WebhookServing.AddFlags(fss.FlagSet("webhook serving")) + } + + o.SecureServing.AddFlags(fss.FlagSet("secure serving")) + o.Authentication.AddFlags(fss.FlagSet("authentication")) + o.Authorization.AddFlags(fss.FlagSet("authorization")) + + fs := fss.FlagSet("misc") + fs.StringVar(&o.Master, "master", o.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig).") + fs.StringVar(&o.Generic.ClientConnection.Kubeconfig, "kubeconfig", o.Generic.ClientConnection.Kubeconfig, "Path to kubeconfig file with authorization and master location information (the master location can be overridden by the master flag).") + fs.DurationVar(&o.NodeStatusUpdateFrequency.Duration, "node-status-update-frequency", o.NodeStatusUpdateFrequency.Duration, "Specifies how often the controller updates nodes' status.") + utilfeature.DefaultMutableFeatureGate.AddFlag(fss.FlagSet("generic")) + + return fss +} + +// ApplyTo fills up cloud controller manager config with options. +func (o *CloudControllerManagerOptions) ApplyTo(c *config.Config, userAgent string) error { + var err error + + // Build kubeconfig first to so that if it fails, it doesn't cause leaking + // goroutines (started from initializing secure serving - which underneath + // creates a queue which in its constructor starts a goroutine). + c.Kubeconfig, err = clientcmd.BuildConfigFromFlags(o.Master, o.Generic.ClientConnection.Kubeconfig) + if err != nil { + return err + } + c.Kubeconfig.DisableCompression = true + c.Kubeconfig.ContentConfig.AcceptContentTypes = o.Generic.ClientConnection.AcceptContentTypes + c.Kubeconfig.ContentConfig.ContentType = o.Generic.ClientConnection.ContentType + c.Kubeconfig.QPS = o.Generic.ClientConnection.QPS + c.Kubeconfig.Burst = int(o.Generic.ClientConnection.Burst) + + if err = o.Generic.ApplyTo(&c.ComponentConfig.Generic); err != nil { + return err + } + if err = o.KubeCloudShared.ApplyTo(&c.ComponentConfig.KubeCloudShared); err != nil { + return err + } + if err = o.ServiceController.ApplyTo(&c.ComponentConfig.ServiceController); err != nil { + return err + } + if o.Webhook != nil { + if err = o.Webhook.ApplyTo(&c.ComponentConfig.Webhook); err != nil { + return err + } + } + if o.WebhookServing != nil { + if err = o.WebhookServing.ApplyTo(&c.WebhookSecureServing); err != nil { + return err + } + } + if err = o.SecureServing.ApplyTo(&c.SecureServing, &c.LoopbackClientConfig); err != nil { + return err + } + if o.SecureServing.BindPort != 0 || o.SecureServing.Listener != nil { + if err = o.Authentication.ApplyTo(&c.Authentication, c.SecureServing, nil); err != nil { + return err + } + if err = o.Authorization.ApplyTo(&c.Authorization); err != nil { + return err + } + } + + c.Client, err = clientset.NewForConfig(restclient.AddUserAgent(c.Kubeconfig, userAgent)) + if err != nil { + return err + } + + c.EventBroadcaster = record.NewBroadcaster() + c.EventRecorder = c.EventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: userAgent}) + + rootClientBuilder := clientbuilder.SimpleControllerClientBuilder{ + ClientConfig: c.Kubeconfig, + } + if c.ComponentConfig.KubeCloudShared.UseServiceAccountCredentials { + c.ClientBuilder = clientbuilder.NewDynamicClientBuilder( + restclient.AnonymousClientConfig(c.Kubeconfig), + c.Client.CoreV1(), + metav1.NamespaceSystem) + } else { + c.ClientBuilder = rootClientBuilder + } + c.VersionedClient = rootClientBuilder.ClientOrDie("shared-informers") + c.SharedInformers = informers.NewSharedInformerFactory(c.VersionedClient, resyncPeriod(c)()) + + // sync back to component config + // TODO: find more elegant way than syncing back the values. + c.ComponentConfig.NodeStatusUpdateFrequency = o.NodeStatusUpdateFrequency + c.ComponentConfig.NodeController.ConcurrentNodeSyncs = o.NodeController.ConcurrentNodeSyncs + + return nil +} + +// Validate is used to validate config before launching the cloud controller manager +func (o *CloudControllerManagerOptions) Validate(allControllers, disabledByDefaultControllers, allWebhooks, disabledByDefaultWebhooks []string) error { + errors := []error{} + + errors = append(errors, o.Generic.Validate(allControllers, disabledByDefaultControllers)...) + errors = append(errors, o.KubeCloudShared.Validate()...) + errors = append(errors, o.ServiceController.Validate()...) + errors = append(errors, o.SecureServing.Validate()...) + errors = append(errors, o.Authentication.Validate()...) + errors = append(errors, o.Authorization.Validate()...) + + if o.Webhook != nil { + errors = append(errors, o.Webhook.Validate(allWebhooks, disabledByDefaultWebhooks)...) + } + if o.WebhookServing != nil { + errors = append(errors, o.WebhookServing.Validate()...) + + if o.WebhookServing.BindPort == o.SecureServing.BindPort { + errors = append(errors, fmt.Errorf("--webhook-secure-port cannot be the same value as --secure-port")) + } + } + if len(o.KubeCloudShared.CloudProvider.Name) == 0 { + errors = append(errors, fmt.Errorf("--cloud-provider cannot be empty")) + } + + return utilerrors.NewAggregate(errors) +} + +// resyncPeriod computes the time interval a shared informer waits before resyncing with the api server +func resyncPeriod(c *config.Config) func() time.Duration { + return func() time.Duration { + factor := rand.Float64() + 1 + return time.Duration(float64(c.ComponentConfig.Generic.MinResyncPeriod.Nanoseconds()) * factor) + } +} + +// Config return a cloud controller manager config objective +func (o *CloudControllerManagerOptions) Config(allControllers, disabledByDefaultControllers, allWebhooks, disabledByDefaultWebhooks []string) (*config.Config, error) { + if err := o.Validate(allControllers, disabledByDefaultControllers, allWebhooks, disabledByDefaultWebhooks); err != nil { + return nil, err + } + + if err := o.SecureServing.MaybeDefaultWithSelfSignedCerts("localhost", nil, []net.IP{netutils.ParseIPSloppy("127.0.0.1")}); err != nil { + return nil, fmt.Errorf("error creating self-signed certificates: %v", err) + } + + if o.WebhookServing != nil { + if err := o.WebhookServing.MaybeDefaultWithSelfSignedCerts("localhost", nil, []net.IP{netutils.ParseIPSloppy("127.0.0.1")}); err != nil { + return nil, fmt.Errorf("error creating self-signed certificates for webhook: %v", err) + } + } + + c := &config.Config{} + if err := o.ApplyTo(c, CloudControllerManagerUserAgent); err != nil { + return nil, err + } + + return c, nil +} diff --git a/vendor/k8s.io/cloud-provider/options/servicecontroller.go b/vendor/k8s.io/cloud-provider/options/servicecontroller.go new file mode 100644 index 0000000000..c63e43a980 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/options/servicecontroller.go @@ -0,0 +1,57 @@ +/* +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 + +import ( + "github.com/spf13/pflag" + serviceconfig "k8s.io/cloud-provider/controllers/service/config" +) + +// ServiceControllerOptions holds the ServiceController options. +type ServiceControllerOptions struct { + *serviceconfig.ServiceControllerConfiguration +} + +// AddFlags adds flags related to ServiceController for controller manager to the specified FlagSet. +func (o *ServiceControllerOptions) AddFlags(fs *pflag.FlagSet) { + if o == nil { + return + } + + fs.Int32Var(&o.ConcurrentServiceSyncs, "concurrent-service-syncs", o.ConcurrentServiceSyncs, "The number of services that are allowed to sync concurrently. Larger number = more responsive service management, but more CPU (and network) load") +} + +// ApplyTo fills up ServiceController config with options. +func (o *ServiceControllerOptions) ApplyTo(cfg *serviceconfig.ServiceControllerConfiguration) error { + if o == nil { + return nil + } + + cfg.ConcurrentServiceSyncs = o.ConcurrentServiceSyncs + + return nil +} + +// Validate checks validation of ServiceControllerOptions. +func (o *ServiceControllerOptions) Validate() []error { + if o == nil { + return nil + } + + errs := []error{} + return errs +} diff --git a/vendor/k8s.io/cloud-provider/options/webhook.go b/vendor/k8s.io/cloud-provider/options/webhook.go new file mode 100644 index 0000000000..719a701025 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/options/webhook.go @@ -0,0 +1,206 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package options + +import ( + "context" + "fmt" + "net" + "strconv" + "strings" + + "github.com/spf13/pflag" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apiserver/pkg/server" + "k8s.io/apiserver/pkg/server/dynamiccertificates" + apiserveroptions "k8s.io/apiserver/pkg/server/options" + "k8s.io/cloud-provider/config" + netutils "k8s.io/utils/net" +) + +const ( + CloudControllerManagerWebhookPort = 10260 +) + +type WebhookOptions struct { + // Webhooks is the list of webhook names that should be enabled or disabled + Webhooks []string +} + +func NewWebhookOptions() *WebhookOptions { + o := &WebhookOptions{} + return o +} + +func (o *WebhookOptions) AddFlags(fs *pflag.FlagSet, allWebhooks, disabledByDefaultWebhooks []string) { + fs.StringSliceVar(&o.Webhooks, "webhooks", o.Webhooks, fmt.Sprintf(""+ + "A list of webhooks to enable. '*' enables all on-by-default webhooks, 'foo' enables the webhook "+ + "named 'foo', '-foo' disables the webhook named 'foo'.\nAll webhooks: %s\nDisabled-by-default webhooks: %s", + strings.Join(allWebhooks, ", "), strings.Join(disabledByDefaultWebhooks, ", "))) +} + +func (o *WebhookOptions) Validate(allWebhooks, disabledByDefaultWebhooks []string) []error { + allErrors := []error{} + + allWebhooksSet := sets.NewString(allWebhooks...) + toValidate := sets.NewString(o.Webhooks...) + toValidate.Insert(disabledByDefaultWebhooks...) + for _, webhook := range toValidate.List() { + if webhook == "*" { + continue + } + webhook = strings.TrimPrefix(webhook, "-") + if !allWebhooksSet.Has(webhook) { + allErrors = append(allErrors, fmt.Errorf("%q is not in the list of known webhooks", webhook)) + } + } + + return allErrors +} + +func (o *WebhookOptions) ApplyTo(cfg *config.WebhookConfiguration) error { + if o == nil { + return nil + } + + cfg.Webhooks = o.Webhooks + + return nil +} + +type WebhookServingOptions struct { + *apiserveroptions.SecureServingOptions +} + +func NewWebhookServingOptions(defaults ProviderDefaults) *WebhookServingOptions { + var ( + bindAddress net.IP + bindPort int + ) + + if defaults.WebhookBindAddress != nil { + bindAddress = *defaults.WebhookBindAddress + } else { + bindAddress = netutils.ParseIPSloppy("0.0.0.0") + } + + if defaults.WebhookBindPort != nil { + bindPort = *defaults.WebhookBindPort + } else { + bindPort = CloudControllerManagerWebhookPort + } + + return &WebhookServingOptions{ + SecureServingOptions: &apiserveroptions.SecureServingOptions{ + BindAddress: bindAddress, + BindPort: bindPort, + ServerCert: apiserveroptions.GeneratableKeyCert{ + CertDirectory: "", + PairName: "cloud-controller-manager-webhook", + }, + }, + } +} + +func (o *WebhookServingOptions) AddFlags(fs *pflag.FlagSet) { + fs.IPVar(&o.BindAddress, "webhook-bind-address", o.BindAddress, ""+ + "The IP address on which to listen for the --webhook-secure-port port. The "+ + "associated interface(s) must be reachable by the rest of the cluster, and by CLI/web "+ + fmt.Sprintf("clients. If set to an unspecified address (0.0.0.0 or ::), all interfaces will be used. If unset, defaults to %v.", o.BindAddress)) + + fs.IntVar(&o.BindPort, "webhook-secure-port", o.BindPort, fmt.Sprintf("Secure port to serve cloud provider webhooks. If unset, defaults to %d.", o.BindPort)) + + fs.StringVar(&o.ServerCert.CertDirectory, "webhook-cert-dir", o.ServerCert.CertDirectory, ""+ + "The directory where the TLS certs are located. "+ + "If --tls-cert-file and --tls-private-key-file are provided, this flag will be ignored.") + + fs.StringVar(&o.ServerCert.CertKey.CertFile, "webhook-tls-cert-file", o.ServerCert.CertKey.CertFile, ""+ + "File containing the default x509 Certificate for HTTPS. (CA cert, if any, concatenated "+ + "after server cert). If HTTPS serving is enabled, and --tls-cert-file and "+ + "--tls-private-key-file are not provided, a self-signed certificate and key "+ + "are generated for the public address and saved to the directory specified by --cert-dir.") + + fs.StringVar(&o.ServerCert.CertKey.KeyFile, "webhook-tls-private-key-file", o.ServerCert.CertKey.KeyFile, + "File containing the default x509 private key matching --tls-cert-file.") +} + +func (o *WebhookServingOptions) Validate() []error { + allErrors := []error{} + if o.BindPort < 0 || o.BindPort > 65535 { + allErrors = append(allErrors, fmt.Errorf("--webhook-secure-port %v must be between 0 and 65535, inclusive. A value of 0 disables the webhook endpoint entirely.", o.BindPort)) + } + + if (len(o.ServerCert.CertKey.CertFile) != 0 || len(o.ServerCert.CertKey.KeyFile) != 0) && o.ServerCert.GeneratedCert != nil { + allErrors = append(allErrors, fmt.Errorf("cert/key file and in-memory certificate cannot both be set")) + } + + return allErrors +} + +func (o *WebhookServingOptions) ApplyTo(cfg **server.SecureServingInfo) error { + if o == nil { + return nil + } + + if o.BindPort <= 0 { + return nil + } + + var err error + var listener net.Listener + addr := net.JoinHostPort(o.BindAddress.String(), strconv.Itoa(o.BindPort)) + + l := net.ListenConfig{} + + listener, o.BindPort, err = createListener(addr, l) + if err != nil { + return fmt.Errorf("failed to create listener: %v", err) + } + + *cfg = &server.SecureServingInfo{ + Listener: listener, + } + + serverCertFile, serverKeyFile := o.ServerCert.CertKey.CertFile, o.ServerCert.CertKey.KeyFile + if len(serverCertFile) != 0 || len(serverKeyFile) != 0 { + var err error + (*cfg).Cert, err = dynamiccertificates.NewDynamicServingContentFromFiles("serving-cert", serverCertFile, serverKeyFile) + if err != nil { + return err + } + } else if o.ServerCert.GeneratedCert != nil { + (*cfg).Cert = o.ServerCert.GeneratedCert + } + + return nil +} + +func createListener(addr string, config net.ListenConfig) (net.Listener, int, error) { + ln, err := config.Listen(context.TODO(), "tcp", addr) + if err != nil { + return nil, 0, fmt.Errorf("failed to listen on %v: %v", addr, err) + } + + // get port + tcpAddr, ok := ln.Addr().(*net.TCPAddr) + if !ok { + ln.Close() + return nil, 0, fmt.Errorf("invalid listen address: %q", ln.Addr().String()) + } + + return ln, tcpAddr.Port, nil +} diff --git a/vendor/k8s.io/cloud-provider/plugins.go b/vendor/k8s.io/cloud-provider/plugins.go index 5300abdb4c..7aa061157d 100644 --- a/vendor/k8s.io/cloud-provider/plugins.go +++ b/vendor/k8s.io/cloud-provider/plugins.go @@ -40,7 +40,6 @@ var ( external bool detail string }{ - {"aws", false, "The AWS provider is deprecated and will be removed in a future release. Please use https://github.com/kubernetes/cloud-provider-aws"}, {"azure", false, "The Azure provider is deprecated and will be removed in a future release. Please use https://github.com/kubernetes-sigs/cloud-provider-azure"}, {"gce", false, "The GCE provider is deprecated and will be removed in a future release. Please use https://github.com/kubernetes/cloud-provider-gcp"}, {"vsphere", false, "The vSphere provider is deprecated and will be removed in a future release. Please use https://github.com/kubernetes/cloud-provider-vsphere"}, diff --git a/vendor/k8s.io/cloud-provider/service/helpers/helper.go b/vendor/k8s.io/cloud-provider/service/helpers/helper.go index 0609361762..e363c7db2c 100644 --- a/vendor/k8s.io/cloud-provider/service/helpers/helper.go +++ b/vendor/k8s.io/cloud-provider/service/helpers/helper.go @@ -101,7 +101,7 @@ func RequestsOnlyLocalTraffic(service *v1.Service) bool { service.Spec.Type != v1.ServiceTypeNodePort { return false } - return service.Spec.ExternalTrafficPolicy == v1.ServiceExternalTrafficPolicyTypeLocal + return service.Spec.ExternalTrafficPolicy == v1.ServiceExternalTrafficPolicyLocal } // NeedsHealthCheck checks if service needs health check. diff --git a/vendor/k8s.io/component-base/config/OWNERS b/vendor/k8s.io/component-base/config/OWNERS new file mode 100644 index 0000000000..7243d3cc82 --- /dev/null +++ b/vendor/k8s.io/component-base/config/OWNERS @@ -0,0 +1,13 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: + - api-approvers +reviewers: + - api-reviewers +labels: + - kind/api-change + - sig/api-machinery + - sig/scheduling diff --git a/vendor/k8s.io/component-base/config/doc.go b/vendor/k8s.io/component-base/config/doc.go new file mode 100644 index 0000000000..dd0a5a53a7 --- /dev/null +++ b/vendor/k8s.io/component-base/config/doc.go @@ -0,0 +1,19 @@ +/* +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. +*/ + +// +k8s:deepcopy-gen=package + +package config // import "k8s.io/component-base/config" diff --git a/vendor/k8s.io/component-base/config/options/leaderelectionconfig.go b/vendor/k8s.io/component-base/config/options/leaderelectionconfig.go new file mode 100644 index 0000000000..bf2a44a0a8 --- /dev/null +++ b/vendor/k8s.io/component-base/config/options/leaderelectionconfig.go @@ -0,0 +1,53 @@ +/* +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 options + +import ( + "github.com/spf13/pflag" + "k8s.io/component-base/config" +) + +// BindLeaderElectionFlags binds the LeaderElectionConfiguration struct fields to a flagset +func BindLeaderElectionFlags(l *config.LeaderElectionConfiguration, fs *pflag.FlagSet) { + fs.BoolVar(&l.LeaderElect, "leader-elect", l.LeaderElect, ""+ + "Start a leader election client and gain leadership before "+ + "executing the main loop. Enable this when running replicated "+ + "components for high availability.") + fs.DurationVar(&l.LeaseDuration.Duration, "leader-elect-lease-duration", l.LeaseDuration.Duration, ""+ + "The duration that non-leader candidates will wait after observing a leadership "+ + "renewal until attempting to acquire leadership of a led but unrenewed leader "+ + "slot. This is effectively the maximum duration that a leader can be stopped "+ + "before it is replaced by another candidate. This is only applicable if leader "+ + "election is enabled.") + fs.DurationVar(&l.RenewDeadline.Duration, "leader-elect-renew-deadline", l.RenewDeadline.Duration, ""+ + "The interval between attempts by the acting master to renew a leadership slot "+ + "before it stops leading. This must be less than the lease duration. "+ + "This is only applicable if leader election is enabled.") + fs.DurationVar(&l.RetryPeriod.Duration, "leader-elect-retry-period", l.RetryPeriod.Duration, ""+ + "The duration the clients should wait between attempting acquisition and renewal "+ + "of a leadership. This is only applicable if leader election is enabled.") + fs.StringVar(&l.ResourceLock, "leader-elect-resource-lock", l.ResourceLock, ""+ + "The type of resource object that is used for locking during "+ + "leader election. Supported options are 'leases', 'endpointsleases' "+ + "and 'configmapsleases'.") + fs.StringVar(&l.ResourceName, "leader-elect-resource-name", l.ResourceName, ""+ + "The name of resource object that is used for locking during "+ + "leader election.") + fs.StringVar(&l.ResourceNamespace, "leader-elect-resource-namespace", l.ResourceNamespace, ""+ + "The namespace of resource object that is used for locking during "+ + "leader election.") +} diff --git a/vendor/k8s.io/component-base/config/types.go b/vendor/k8s.io/component-base/config/types.go new file mode 100644 index 0000000000..e1b9469d76 --- /dev/null +++ b/vendor/k8s.io/component-base/config/types.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 config + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ClientConnectionConfiguration contains details for constructing a client. +type ClientConnectionConfiguration struct { + // kubeconfig is the path to a KubeConfig file. + Kubeconfig string + // acceptContentTypes defines the Accept header sent by clients when connecting to a server, overriding the + // default value of 'application/json'. This field will control all connections to the server used by a particular + // client. + AcceptContentTypes string + // contentType is the content type used when sending data to the server from this client. + ContentType string + // qps controls the number of queries per second allowed for this connection. + QPS float32 + // burst allows extra queries to accumulate when a client is exceeding its rate. + Burst int32 +} + +// LeaderElectionConfiguration defines the configuration of leader election +// clients for components that can run with leader election enabled. +type LeaderElectionConfiguration struct { + // leaderElect enables a leader election client to gain leadership + // before executing the main loop. Enable this when running replicated + // components for high availability. + LeaderElect bool + // leaseDuration is the duration that non-leader candidates will wait + // after observing a leadership renewal until attempting to acquire + // leadership of a led but unrenewed leader slot. This is effectively the + // maximum duration that a leader can be stopped before it is replaced + // by another candidate. This is only applicable if leader election is + // enabled. + LeaseDuration metav1.Duration + // renewDeadline is the interval between attempts by the acting master to + // renew a leadership slot before it stops leading. This must be less + // than or equal to the lease duration. This is only applicable if leader + // election is enabled. + RenewDeadline metav1.Duration + // retryPeriod is the duration the clients should wait between attempting + // acquisition and renewal of a leadership. This is only applicable if + // leader election is enabled. + RetryPeriod metav1.Duration + // resourceLock indicates the resource object type that will be used to lock + // during leader election cycles. + ResourceLock string + // resourceName indicates the name of resource object that will be used to lock + // during leader election cycles. + ResourceName string + // resourceNamespace indicates the namespace of resource object that will be used to lock + // during leader election cycles. + ResourceNamespace string +} + +// DebuggingConfiguration holds configuration for Debugging related features. +type DebuggingConfiguration struct { + // enableProfiling enables profiling via web interface host:port/debug/pprof/ + EnableProfiling bool + // enableContentionProfiling enables block profiling, if + // enableProfiling is true. + EnableContentionProfiling bool +} diff --git a/vendor/k8s.io/component-base/config/v1alpha1/conversion.go b/vendor/k8s.io/component-base/config/v1alpha1/conversion.go new file mode 100644 index 0000000000..e2951e310d --- /dev/null +++ b/vendor/k8s.io/component-base/config/v1alpha1/conversion.go @@ -0,0 +1,53 @@ +/* +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 v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/conversion" + "k8s.io/component-base/config" +) + +// Important! The public back-and-forth conversion functions for the types in this generic +// package with ComponentConfig types need to be manually exposed like this in order for +// other packages that reference this package to be able to call these conversion functions +// in an autogenerated manner. +// TODO: Fix the bug in conversion-gen so it automatically discovers these Convert_* functions +// in autogenerated code as well. + +func Convert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(in *ClientConnectionConfiguration, out *config.ClientConnectionConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(in, out, s) +} + +func Convert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(in *config.ClientConnectionConfiguration, out *ClientConnectionConfiguration, s conversion.Scope) error { + return autoConvert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(in, out, s) +} + +func Convert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(in *DebuggingConfiguration, out *config.DebuggingConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(in, out, s) +} + +func Convert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(in *config.DebuggingConfiguration, out *DebuggingConfiguration, s conversion.Scope) error { + return autoConvert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(in, out, s) +} + +func Convert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(in *LeaderElectionConfiguration, out *config.LeaderElectionConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(in, out, s) +} + +func Convert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(in *config.LeaderElectionConfiguration, out *LeaderElectionConfiguration, s conversion.Scope) error { + return autoConvert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/component-base/config/v1alpha1/defaults.go b/vendor/k8s.io/component-base/config/v1alpha1/defaults.go new file mode 100644 index 0000000000..cd7f820e97 --- /dev/null +++ b/vendor/k8s.io/component-base/config/v1alpha1/defaults.go @@ -0,0 +1,98 @@ +/* +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 v1alpha1 + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilpointer "k8s.io/utils/pointer" +) + +// RecommendedDefaultLeaderElectionConfiguration defaults a pointer to a +// LeaderElectionConfiguration struct. This will set the recommended default +// values, but they may be subject to change between API versions. This function +// is intentionally not registered in the scheme as a "normal" `SetDefaults_Foo` +// function to allow consumers of this type to set whatever defaults for their +// embedded configs. Forcing consumers to use these defaults would be problematic +// as defaulting in the scheme is done as part of the conversion, and there would +// be no easy way to opt-out. Instead, if you want to use this defaulting method +// run it in your wrapper struct of this type in its `SetDefaults_` method. +func RecommendedDefaultLeaderElectionConfiguration(obj *LeaderElectionConfiguration) { + zero := metav1.Duration{} + if obj.LeaseDuration == zero { + obj.LeaseDuration = metav1.Duration{Duration: 15 * time.Second} + } + if obj.RenewDeadline == zero { + obj.RenewDeadline = metav1.Duration{Duration: 10 * time.Second} + } + if obj.RetryPeriod == zero { + obj.RetryPeriod = metav1.Duration{Duration: 2 * time.Second} + } + if obj.ResourceLock == "" { + // TODO(#80289): Figure out how to migrate to LeaseLock at this point. + // This will most probably require going through EndpointsLease first. + obj.ResourceLock = EndpointsResourceLock + } + if obj.LeaderElect == nil { + obj.LeaderElect = utilpointer.BoolPtr(true) + } +} + +// RecommendedDefaultClientConnectionConfiguration defaults a pointer to a +// ClientConnectionConfiguration struct. This will set the recommended default +// values, but they may be subject to change between API versions. This function +// is intentionally not registered in the scheme as a "normal" `SetDefaults_Foo` +// function to allow consumers of this type to set whatever defaults for their +// embedded configs. Forcing consumers to use these defaults would be problematic +// as defaulting in the scheme is done as part of the conversion, and there would +// be no easy way to opt-out. Instead, if you want to use this defaulting method +// run it in your wrapper struct of this type in its `SetDefaults_` method. +func RecommendedDefaultClientConnectionConfiguration(obj *ClientConnectionConfiguration) { + if len(obj.ContentType) == 0 { + obj.ContentType = "application/vnd.kubernetes.protobuf" + } + if obj.QPS == 0.0 { + obj.QPS = 50.0 + } + if obj.Burst == 0 { + obj.Burst = 100 + } +} + +// RecommendedDebuggingConfiguration defaults profiling and debugging configuration. +// This will set the recommended default +// values, but they may be subject to change between API versions. This function +// is intentionally not registered in the scheme as a "normal" `SetDefaults_Foo` +// function to allow consumers of this type to set whatever defaults for their +// embedded configs. Forcing consumers to use these defaults would be problematic +// as defaulting in the scheme is done as part of the conversion, and there would +// be no easy way to opt-out. Instead, if you want to use this defaulting method +// run it in your wrapper struct of this type in its `SetDefaults_` method. +func RecommendedDebuggingConfiguration(obj *DebuggingConfiguration) { + if obj.EnableProfiling == nil { + obj.EnableProfiling = utilpointer.BoolPtr(true) // profile debugging is cheap to have exposed and standard on kube binaries + } +} + +// NewRecommendedDebuggingConfiguration returns the current recommended DebuggingConfiguration. +// This may change between releases as recommendations shift. +func NewRecommendedDebuggingConfiguration() *DebuggingConfiguration { + ret := &DebuggingConfiguration{} + RecommendedDebuggingConfiguration(ret) + return ret +} diff --git a/vendor/k8s.io/component-base/config/v1alpha1/doc.go b/vendor/k8s.io/component-base/config/v1alpha1/doc.go new file mode 100644 index 0000000000..3cd4f4292e --- /dev/null +++ b/vendor/k8s.io/component-base/config/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +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. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=k8s.io/component-base/config + +package v1alpha1 // import "k8s.io/component-base/config/v1alpha1" diff --git a/vendor/k8s.io/component-base/config/v1alpha1/register.go b/vendor/k8s.io/component-base/config/v1alpha1/register.go new file mode 100644 index 0000000000..ddc186c9aa --- /dev/null +++ b/vendor/k8s.io/component-base/config/v1alpha1/register.go @@ -0,0 +1,31 @@ +/* +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 v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" +) + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder runtime.SchemeBuilder + // localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package, + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) diff --git a/vendor/k8s.io/component-base/config/v1alpha1/types.go b/vendor/k8s.io/component-base/config/v1alpha1/types.go new file mode 100644 index 0000000000..3c5f004f27 --- /dev/null +++ b/vendor/k8s.io/component-base/config/v1alpha1/types.go @@ -0,0 +1,82 @@ +/* +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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const EndpointsResourceLock = "endpoints" + +// LeaderElectionConfiguration defines the configuration of leader election +// clients for components that can run with leader election enabled. +type LeaderElectionConfiguration struct { + // leaderElect enables a leader election client to gain leadership + // before executing the main loop. Enable this when running replicated + // components for high availability. + LeaderElect *bool `json:"leaderElect"` + // leaseDuration is the duration that non-leader candidates will wait + // after observing a leadership renewal until attempting to acquire + // leadership of a led but unrenewed leader slot. This is effectively the + // maximum duration that a leader can be stopped before it is replaced + // by another candidate. This is only applicable if leader election is + // enabled. + LeaseDuration metav1.Duration `json:"leaseDuration"` + // renewDeadline is the interval between attempts by the acting master to + // renew a leadership slot before it stops leading. This must be less + // than or equal to the lease duration. This is only applicable if leader + // election is enabled. + RenewDeadline metav1.Duration `json:"renewDeadline"` + // retryPeriod is the duration the clients should wait between attempting + // acquisition and renewal of a leadership. This is only applicable if + // leader election is enabled. + RetryPeriod metav1.Duration `json:"retryPeriod"` + // resourceLock indicates the resource object type that will be used to lock + // during leader election cycles. + ResourceLock string `json:"resourceLock"` + // resourceName indicates the name of resource object that will be used to lock + // during leader election cycles. + ResourceName string `json:"resourceName"` + // resourceName indicates the namespace of resource object that will be used to lock + // during leader election cycles. + ResourceNamespace string `json:"resourceNamespace"` +} + +// DebuggingConfiguration holds configuration for Debugging related features. +type DebuggingConfiguration struct { + // enableProfiling enables profiling via web interface host:port/debug/pprof/ + EnableProfiling *bool `json:"enableProfiling,omitempty"` + // enableContentionProfiling enables block profiling, if + // enableProfiling is true. + EnableContentionProfiling *bool `json:"enableContentionProfiling,omitempty"` +} + +// ClientConnectionConfiguration contains details for constructing a client. +type ClientConnectionConfiguration struct { + // kubeconfig is the path to a KubeConfig file. + Kubeconfig string `json:"kubeconfig"` + // acceptContentTypes defines the Accept header sent by clients when connecting to a server, overriding the + // default value of 'application/json'. This field will control all connections to the server used by a particular + // client. + AcceptContentTypes string `json:"acceptContentTypes"` + // contentType is the content type used when sending data to the server from this client. + ContentType string `json:"contentType"` + // qps controls the number of queries per second allowed for this connection. + QPS float32 `json:"qps"` + // burst allows extra queries to accumulate when a client is exceeding its rate. + Burst int32 `json:"burst"` +} diff --git a/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.conversion.go new file mode 100644 index 0000000000..a911bb50d8 --- /dev/null +++ b/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.conversion.go @@ -0,0 +1,133 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 conversion-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + config "k8s.io/component-base/config" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddConversionFunc((*config.ClientConnectionConfiguration)(nil), (*ClientConnectionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(a.(*config.ClientConnectionConfiguration), b.(*ClientConnectionConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*config.DebuggingConfiguration)(nil), (*DebuggingConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(a.(*config.DebuggingConfiguration), b.(*DebuggingConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*config.LeaderElectionConfiguration)(nil), (*LeaderElectionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(a.(*config.LeaderElectionConfiguration), b.(*LeaderElectionConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*ClientConnectionConfiguration)(nil), (*config.ClientConnectionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(a.(*ClientConnectionConfiguration), b.(*config.ClientConnectionConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*DebuggingConfiguration)(nil), (*config.DebuggingConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(a.(*DebuggingConfiguration), b.(*config.DebuggingConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*LeaderElectionConfiguration)(nil), (*config.LeaderElectionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(a.(*LeaderElectionConfiguration), b.(*config.LeaderElectionConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(in *ClientConnectionConfiguration, out *config.ClientConnectionConfiguration, s conversion.Scope) error { + out.Kubeconfig = in.Kubeconfig + out.AcceptContentTypes = in.AcceptContentTypes + out.ContentType = in.ContentType + out.QPS = in.QPS + out.Burst = in.Burst + return nil +} + +func autoConvert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(in *config.ClientConnectionConfiguration, out *ClientConnectionConfiguration, s conversion.Scope) error { + out.Kubeconfig = in.Kubeconfig + out.AcceptContentTypes = in.AcceptContentTypes + out.ContentType = in.ContentType + out.QPS = in.QPS + out.Burst = in.Burst + return nil +} + +func autoConvert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(in *DebuggingConfiguration, out *config.DebuggingConfiguration, s conversion.Scope) error { + if err := v1.Convert_Pointer_bool_To_bool(&in.EnableProfiling, &out.EnableProfiling, s); err != nil { + return err + } + if err := v1.Convert_Pointer_bool_To_bool(&in.EnableContentionProfiling, &out.EnableContentionProfiling, s); err != nil { + return err + } + return nil +} + +func autoConvert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(in *config.DebuggingConfiguration, out *DebuggingConfiguration, s conversion.Scope) error { + if err := v1.Convert_bool_To_Pointer_bool(&in.EnableProfiling, &out.EnableProfiling, s); err != nil { + return err + } + if err := v1.Convert_bool_To_Pointer_bool(&in.EnableContentionProfiling, &out.EnableContentionProfiling, s); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(in *LeaderElectionConfiguration, out *config.LeaderElectionConfiguration, s conversion.Scope) error { + if err := v1.Convert_Pointer_bool_To_bool(&in.LeaderElect, &out.LeaderElect, s); err != nil { + return err + } + out.LeaseDuration = in.LeaseDuration + out.RenewDeadline = in.RenewDeadline + out.RetryPeriod = in.RetryPeriod + out.ResourceLock = in.ResourceLock + out.ResourceName = in.ResourceName + out.ResourceNamespace = in.ResourceNamespace + return nil +} + +func autoConvert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(in *config.LeaderElectionConfiguration, out *LeaderElectionConfiguration, s conversion.Scope) error { + if err := v1.Convert_bool_To_Pointer_bool(&in.LeaderElect, &out.LeaderElect, s); err != nil { + return err + } + out.LeaseDuration = in.LeaseDuration + out.RenewDeadline = in.RenewDeadline + out.RetryPeriod = in.RetryPeriod + out.ResourceLock = in.ResourceLock + out.ResourceName = in.ResourceName + out.ResourceNamespace = in.ResourceNamespace + return nil +} diff --git a/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..92176d9944 --- /dev/null +++ b/vendor/k8s.io/component-base/config/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,88 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClientConnectionConfiguration) DeepCopyInto(out *ClientConnectionConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientConnectionConfiguration. +func (in *ClientConnectionConfiguration) DeepCopy() *ClientConnectionConfiguration { + if in == nil { + return nil + } + out := new(ClientConnectionConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DebuggingConfiguration) DeepCopyInto(out *DebuggingConfiguration) { + *out = *in + if in.EnableProfiling != nil { + in, out := &in.EnableProfiling, &out.EnableProfiling + *out = new(bool) + **out = **in + } + if in.EnableContentionProfiling != nil { + in, out := &in.EnableContentionProfiling, &out.EnableContentionProfiling + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DebuggingConfiguration. +func (in *DebuggingConfiguration) DeepCopy() *DebuggingConfiguration { + if in == nil { + return nil + } + out := new(DebuggingConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaderElectionConfiguration) DeepCopyInto(out *LeaderElectionConfiguration) { + *out = *in + if in.LeaderElect != nil { + in, out := &in.LeaderElect, &out.LeaderElect + *out = new(bool) + **out = **in + } + out.LeaseDuration = in.LeaseDuration + out.RenewDeadline = in.RenewDeadline + out.RetryPeriod = in.RetryPeriod + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaderElectionConfiguration. +func (in *LeaderElectionConfiguration) DeepCopy() *LeaderElectionConfiguration { + if in == nil { + return nil + } + out := new(LeaderElectionConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/component-base/config/zz_generated.deepcopy.go b/vendor/k8s.io/component-base/config/zz_generated.deepcopy.go new file mode 100644 index 0000000000..fb0c1f1e6a --- /dev/null +++ b/vendor/k8s.io/component-base/config/zz_generated.deepcopy.go @@ -0,0 +1,73 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 deepcopy-gen. DO NOT EDIT. + +package config + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClientConnectionConfiguration) DeepCopyInto(out *ClientConnectionConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientConnectionConfiguration. +func (in *ClientConnectionConfiguration) DeepCopy() *ClientConnectionConfiguration { + if in == nil { + return nil + } + out := new(ClientConnectionConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DebuggingConfiguration) DeepCopyInto(out *DebuggingConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DebuggingConfiguration. +func (in *DebuggingConfiguration) DeepCopy() *DebuggingConfiguration { + if in == nil { + return nil + } + out := new(DebuggingConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaderElectionConfiguration) DeepCopyInto(out *LeaderElectionConfiguration) { + *out = *in + out.LeaseDuration = in.LeaseDuration + out.RenewDeadline = in.RenewDeadline + out.RetryPeriod = in.RetryPeriod + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaderElectionConfiguration. +func (in *LeaderElectionConfiguration) DeepCopy() *LeaderElectionConfiguration { + if in == nil { + return nil + } + out := new(LeaderElectionConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/component-base/logs/OWNERS b/vendor/k8s.io/component-base/logs/OWNERS new file mode 100644 index 0000000000..57f049d79d --- /dev/null +++ b/vendor/k8s.io/component-base/logs/OWNERS @@ -0,0 +1,12 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - sig-instrumentation-approvers + - serathius + - pohly +reviewers: + - sig-instrumentation-reviewers + - serathius +labels: + - sig/instrumentation + - wg/structured-logging diff --git a/vendor/k8s.io/component-base/logs/api/v1/options.go b/vendor/k8s.io/component-base/logs/api/v1/options.go index 6270b2eb96..a5e11f7d86 100644 --- a/vendor/k8s.io/component-base/logs/api/v1/options.go +++ b/vendor/k8s.io/component-base/logs/api/v1/options.go @@ -19,7 +19,9 @@ package v1 import ( "flag" "fmt" + "io" "math" + "os" "strings" "time" @@ -31,6 +33,7 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" cliflag "k8s.io/component-base/cli/flag" "k8s.io/component-base/featuregate" + "k8s.io/component-base/logs/internal/setverbositylevel" "k8s.io/component-base/logs/klogflags" ) @@ -62,18 +65,41 @@ func NewLoggingConfiguration() *LoggingConfiguration { // The optional FeatureGate controls logging features. If nil, the default for // these features is used. func ValidateAndApply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error { - return ValidateAndApplyAsField(c, featureGate, nil) + return validateAndApply(c, nil, featureGate, nil) +} + +// ValidateAndApplyWithOptions is a variant of ValidateAndApply which accepts +// additional options beyond those that can be configured through the API. This +// is meant for testing. +func ValidateAndApplyWithOptions(c *LoggingConfiguration, options *LoggingOptions, featureGate featuregate.FeatureGate) error { + return validateAndApply(c, options, featureGate, nil) +} + +// +k8s:deepcopy-gen=false + +// LoggingOptions can be used with ValidateAndApplyWithOptions to override +// certain global defaults. +type LoggingOptions struct { + // ErrorStream can be used to override the os.Stderr default. + ErrorStream io.Writer + + // InfoStream can be used to override the os.Stdout default. + InfoStream io.Writer } // ValidateAndApplyAsField is a variant of ValidateAndApply that should be used // when the LoggingConfiguration is embedded in some larger configuration // structure. func ValidateAndApplyAsField(c *LoggingConfiguration, featureGate featuregate.FeatureGate, fldPath *field.Path) error { + return validateAndApply(c, nil, featureGate, fldPath) +} + +func validateAndApply(c *LoggingConfiguration, options *LoggingOptions, featureGate featuregate.FeatureGate, fldPath *field.Path) error { errs := Validate(c, featureGate, fldPath) if len(errs) > 0 { return errs.ToAggregate() } - return apply(c, featureGate) + return apply(c, options, featureGate) } // Validate can be used to check for invalid settings without applying them. @@ -156,7 +182,7 @@ func featureEnabled(featureGate featuregate.FeatureGate, feature featuregate.Fea return enabled } -func apply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error { +func apply(c *LoggingConfiguration, options *LoggingOptions, featureGate featuregate.FeatureGate) error { contextualLoggingEnabled := contextualLoggingDefault if featureGate != nil { contextualLoggingEnabled = featureGate.Enabled(ContextualLogging) @@ -167,8 +193,19 @@ func apply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error { if format.factory == nil { klog.ClearLogger() } else { - log, flush := format.factory.Create(*c) - klog.SetLoggerWithOptions(log, klog.ContextualLogger(contextualLoggingEnabled), klog.FlushLogger(flush)) + if options == nil { + options = &LoggingOptions{ + ErrorStream: os.Stderr, + InfoStream: os.Stdout, + } + } + log, control := format.factory.Create(*c, *options) + if control.SetVerbosityLevel != nil { + setverbositylevel.Mutex.Lock() + defer setverbositylevel.Mutex.Unlock() + setverbositylevel.Callbacks = append(setverbositylevel.Callbacks, control.SetVerbosityLevel) + } + klog.SetLoggerWithOptions(log, klog.ContextualLogger(contextualLoggingEnabled), klog.FlushLogger(control.Flush)) } if err := loggingFlags.Lookup("v").Value.Set(VerbosityLevelPflag(&c.Verbosity).String()); err != nil { return fmt.Errorf("internal error while setting klog verbosity: %v", err) @@ -183,6 +220,41 @@ func apply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error { // AddFlags adds command line flags for the configuration. func AddFlags(c *LoggingConfiguration, fs *pflag.FlagSet) { + addFlags(c, fs) +} + +// AddGoFlags is a variant of AddFlags for a standard FlagSet. +func AddGoFlags(c *LoggingConfiguration, fs *flag.FlagSet) { + addFlags(c, goFlagSet{FlagSet: fs}) +} + +// flagSet is the interface implemented by pflag.FlagSet, with +// just those methods defined which are needed by addFlags. +type flagSet interface { + BoolVar(p *bool, name string, value bool, usage string) + DurationVar(p *time.Duration, name string, value time.Duration, usage string) + StringVar(p *string, name string, value string, usage string) + Var(value pflag.Value, name string, usage string) + VarP(value pflag.Value, name, shorthand, usage string) +} + +// goFlagSet implements flagSet for a stdlib flag.FlagSet. +type goFlagSet struct { + *flag.FlagSet +} + +func (fs goFlagSet) Var(value pflag.Value, name string, usage string) { + fs.FlagSet.Var(value, name, usage) +} + +func (fs goFlagSet) VarP(value pflag.Value, name, shorthand, usage string) { + // Ignore shorthand, it's not needed and not supported. + fs.FlagSet.Var(value, name, usage) +} + +// addFlags can be used with both flag.FlagSet and pflag.FlagSet. The internal +// interface definition avoids duplicating this code. +func addFlags(c *LoggingConfiguration, fs flagSet) { formats := logRegistry.list() fs.StringVar(&c.Format, "logging-format", c.Format, fmt.Sprintf("Sets the log format. Permitted formats: %s.", formats)) // No new log formats should be added after generation is of flag options diff --git a/vendor/k8s.io/component-base/logs/api/v1/pflags.go b/vendor/k8s.io/component-base/logs/api/v1/pflags.go index 36a98cc81c..b74e132a72 100644 --- a/vendor/k8s.io/component-base/logs/api/v1/pflags.go +++ b/vendor/k8s.io/component-base/logs/api/v1/pflags.go @@ -36,6 +36,9 @@ type vmoduleConfigurationPFlag struct { // String returns the -vmodule parameter (comma-separated list of pattern=N). func (wrapper vmoduleConfigurationPFlag) String() string { + if wrapper.value == nil { + return "" + } var patterns []string for _, item := range *wrapper.value { patterns = append(patterns, fmt.Sprintf("%s=%d", item.FilePattern, item.Verbosity)) @@ -82,10 +85,16 @@ type verbosityLevelPflag struct { } func (wrapper verbosityLevelPflag) String() string { + if wrapper.value == nil { + return "0" + } return strconv.FormatInt(int64(*wrapper.value), 10) } func (wrapper verbosityLevelPflag) Get() interface{} { + if wrapper.value == nil { + return VerbosityLevel(0) + } return *wrapper.value } diff --git a/vendor/k8s.io/component-base/logs/api/v1/registry.go b/vendor/k8s.io/component-base/logs/api/v1/registry.go index 78bc8f8853..f8fc1f2cae 100644 --- a/vendor/k8s.io/component-base/logs/api/v1/registry.go +++ b/vendor/k8s.io/component-base/logs/api/v1/registry.go @@ -39,14 +39,29 @@ type logFormat struct { feature featuregate.Feature } +// +k8s:deepcopy-gen=false + +// RuntimeControl provides operations that aren't available through the normal +// Logger or LogSink API. +type RuntimeControl struct { + // Flush ensures that all in-memory data is written. + // May be nil. + Flush func() + + // SetVerbosityLevel changes the level for all Logger instances + // derived from the initial one. May be nil. + // + // The parameter is intentionally a plain uint32 instead of + // VerbosityLevel to enable implementations that don't need to import + // the API (helps avoid circular dependencies). + SetVerbosityLevel func(v uint32) error +} + // LogFormatFactory provides support for a certain additional, // non-default log format. type LogFormatFactory interface { // Create returns a logger with the requested configuration. - // Returning a flush function for the logger is optional. - // If provided, the caller must ensure that it is called - // periodically (if desired) and at program exit. - Create(c LoggingConfiguration) (log logr.Logger, flush func()) + Create(c LoggingConfiguration, o LoggingOptions) (logr.Logger, RuntimeControl) } // RegisterLogFormat registers support for a new logging format. This must be called diff --git a/vendor/k8s.io/component-base/logs/internal/setverbositylevel/setverbositylevel.go b/vendor/k8s.io/component-base/logs/internal/setverbositylevel/setverbositylevel.go new file mode 100644 index 0000000000..c643bae9bc --- /dev/null +++ b/vendor/k8s.io/component-base/logs/internal/setverbositylevel/setverbositylevel.go @@ -0,0 +1,34 @@ +/* +Copyright 2022 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 setverbositylevel stores callbacks that will be invoked by logs.GlogLevel. +// +// This is a separate package to avoid a dependency from +// k8s.io/component-base/logs (uses the callbacks) to +// k8s.io/component-base/logs/api/v1 (adds them). Not all users of the logs +// package also use the API. +package setverbositylevel + +import ( + "sync" +) + +var ( + // Mutex controls access to the callbacks. + Mutex sync.Mutex + + Callbacks []func(v uint32) error +) diff --git a/vendor/k8s.io/component-base/logs/logs.go b/vendor/k8s.io/component-base/logs/logs.go new file mode 100644 index 0000000000..7fda0f9117 --- /dev/null +++ b/vendor/k8s.io/component-base/logs/logs.go @@ -0,0 +1,209 @@ +/* +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 logs contains support for logging options, flags and setup. +// Commands must explicitly enable command line flags. They no longer +// get added automatically when importing this package. +package logs + +import ( + "flag" + "fmt" + "log" + "strconv" + "time" + + "github.com/spf13/pflag" + logsapi "k8s.io/component-base/logs/api/v1" + "k8s.io/component-base/logs/internal/setverbositylevel" + "k8s.io/component-base/logs/klogflags" + "k8s.io/klog/v2" +) + +const vmoduleUsage = " (only works for the default text log format)" + +var ( + packageFlags = flag.NewFlagSet("logging", flag.ContinueOnError) + + // Periodic flushing gets configured either via the global flag + // in this file or via LoggingConfiguration. + logFlushFreq time.Duration +) + +func init() { + klogflags.Init(packageFlags) + packageFlags.DurationVar(&logFlushFreq, logsapi.LogFlushFreqFlagName, logsapi.LogFlushFreqDefault, "Maximum number of seconds between log flushes") +} + +type addFlagsOptions struct { + skipLoggingConfigurationFlags bool +} + +type Option func(*addFlagsOptions) + +// SkipLoggingConfigurationFlags must be used as option for AddFlags when +// the program also uses a LoggingConfiguration struct for configuring +// logging. Then only flags not covered by that get added. +func SkipLoggingConfigurationFlags() Option { + return func(o *addFlagsOptions) { + o.skipLoggingConfigurationFlags = true + } +} + +// Options is an alias for LoggingConfiguration to comply with component-base +// conventions. +type Options = logsapi.LoggingConfiguration + +// NewOptions is an alias for NewLoggingConfiguration. +var NewOptions = logsapi.NewLoggingConfiguration + +// AddFlags registers this package's flags on arbitrary FlagSets. This includes +// the klog flags, with the original underscore as separator between. If +// commands want hyphens as separators, they can set +// k8s.io/component-base/cli/flag/WordSepNormalizeFunc as normalization +// function on the flag set before calling AddFlags. +// +// May be called more than once. +func AddFlags(fs *pflag.FlagSet, opts ...Option) { + o := addFlagsOptions{} + for _, opt := range opts { + opt(&o) + } + + // Add all supported flags. + packageFlags.VisitAll(func(f *flag.Flag) { + pf := pflag.PFlagFromGoFlag(f) + switch f.Name { + case "v", logsapi.LogFlushFreqFlagName: + // unchanged, potentially skip it + if o.skipLoggingConfigurationFlags { + return + } + case "vmodule": + if o.skipLoggingConfigurationFlags { + return + } + pf.Usage += vmoduleUsage + } + if fs.Lookup(pf.Name) == nil { + fs.AddFlag(pf) + } + }) +} + +// AddGoFlags is a variant of AddFlags for traditional Go flag.FlagSet. +// Commands should use pflag whenever possible for the sake of consistency. +// Cases where this function is needed include tests (they have to set up flags +// in flag.CommandLine) and commands that for historic reasons use Go +// flag.Parse and cannot change to pflag because it would break their command +// line interface. +func AddGoFlags(fs *flag.FlagSet, opts ...Option) { + o := addFlagsOptions{} + for _, opt := range opts { + opt(&o) + } + + // Add flags with deprecation remark added to the usage text of + // some klog flags. + packageFlags.VisitAll(func(f *flag.Flag) { + usage := f.Usage + switch f.Name { + case "v", logsapi.LogFlushFreqFlagName: + // unchanged + if o.skipLoggingConfigurationFlags { + return + } + case "vmodule": + if o.skipLoggingConfigurationFlags { + return + } + usage += vmoduleUsage + } + fs.Var(f.Value, f.Name, usage) + }) +} + +// KlogWriter serves as a bridge between the standard log package and the glog package. +type KlogWriter struct{} + +// Write implements the io.Writer interface. +func (writer KlogWriter) Write(data []byte) (n int, err error) { + klog.InfoDepth(1, string(data)) + return len(data), nil +} + +// InitLogs initializes logs the way we want for Kubernetes. +// It should be called after parsing flags. If called before that, +// it will use the default log settings. +// +// InitLogs disables support for contextual logging in klog while +// that Kubernetes feature is not considered stable yet. Commands +// which want to support contextual logging can: +// - call klog.EnableContextualLogging after calling InitLogs, +// with a fixed `true` or depending on some command line flag or +// a feature gate check +// - set up a FeatureGate instance, the advanced logging configuration +// with Options and call Options.ValidateAndApply with the FeatureGate; +// k8s.io/component-base/logs/example/cmd demonstrates how to do that +func InitLogs() { + log.SetOutput(KlogWriter{}) + log.SetFlags(0) + + // Start flushing now. If LoggingConfiguration.ApplyAndValidate is + // used, it will restart the daemon with the log flush interval defined + // there. + klog.StartFlushDaemon(logFlushFreq) + + // This is the default in Kubernetes. Options.ValidateAndApply + // will override this with the result of a feature gate check. + klog.EnableContextualLogging(false) +} + +// FlushLogs flushes logs immediately. This should be called at the end of +// the main function via defer to ensure that all pending log messages +// are printed before exiting the program. +func FlushLogs() { + klog.Flush() +} + +// NewLogger creates a new log.Logger which sends logs to klog.Info. +func NewLogger(prefix string) *log.Logger { + return log.New(KlogWriter{}, prefix, 0) +} + +// GlogSetter modifies the verbosity threshold for the entire program. +// Some components have HTTP-based APIs for invoking this at runtime. +func GlogSetter(val string) (string, error) { + v, err := strconv.ParseUint(val, 10, 32) + if err != nil { + return "", err + } + + var level klog.Level + if err := level.Set(val); err != nil { + return "", fmt.Errorf("failed set klog.logging.verbosity %s: %v", val, err) + } + + setverbositylevel.Mutex.Lock() + defer setverbositylevel.Mutex.Unlock() + for _, cb := range setverbositylevel.Callbacks { + if err := cb(uint32(v)); err != nil { + return "", err + } + } + + return fmt.Sprintf("successfully set klog.logging.verbosity to %s", val), nil +} diff --git a/vendor/k8s.io/component-base/metrics/features/kube_features.go b/vendor/k8s.io/component-base/metrics/features/kube_features.go new file mode 100644 index 0000000000..3cd6c22afa --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/features/kube_features.go @@ -0,0 +1,39 @@ +/* +Copyright 2022 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 features + +import ( + "k8s.io/component-base/featuregate" +) + +const ( + // owner: @logicalhan + // kep: https://kep.k8s.io/3466 + // alpha: v1.26 + ComponentSLIs featuregate.Feature = "ComponentSLIs" +) + +func featureGates() map[featuregate.Feature]featuregate.FeatureSpec { + return map[featuregate.Feature]featuregate.FeatureSpec{ + ComponentSLIs: {Default: true, PreRelease: featuregate.Beta}, + } +} + +// AddFeatureGates adds all feature gates used by this package. +func AddFeatureGates(mutableFeatureGate featuregate.MutableFeatureGate) error { + return mutableFeatureGate.Add(featureGates()) +} diff --git a/vendor/k8s.io/component-base/metrics/legacyregistry/registry.go b/vendor/k8s.io/component-base/metrics/legacyregistry/registry.go index ed0f1c348b..79c806d8b2 100644 --- a/vendor/k8s.io/component-base/metrics/legacyregistry/registry.go +++ b/vendor/k8s.io/component-base/metrics/legacyregistry/registry.go @@ -42,6 +42,9 @@ var ( // Register registers a collectable metric but uses the global registry Register = defaultRegistry.Register + + // Registerer exposes the global registerer + Registerer = defaultRegistry.Registerer ) func init() { diff --git a/vendor/k8s.io/component-base/metrics/metric.go b/vendor/k8s.io/component-base/metrics/metric.go index cf5bccfa7b..3b22d21ef2 100644 --- a/vendor/k8s.io/component-base/metrics/metric.go +++ b/vendor/k8s.io/component-base/metrics/metric.go @@ -97,9 +97,8 @@ func (r *lazyMetric) lazyInit(self kubeCollector, fqName string) { // 2. if the metric is manually disabled via a CLI flag. // // Disclaimer: disabling a metric via a CLI flag has higher precedence than -// -// deprecation and will override show-hidden-metrics for the explicitly -// disabled metric. +// deprecation and will override show-hidden-metrics for the explicitly +// disabled metric. func (r *lazyMetric) preprocessMetric(version semver.Version) { disabledMetricsLock.RLock() defer disabledMetricsLock.RUnlock() @@ -216,7 +215,6 @@ var noopCounterVec = &prometheus.CounterVec{} var noopHistogramVec = &prometheus.HistogramVec{} var noopTimingHistogramVec = &promext.TimingHistogramVec{} var noopGaugeVec = &prometheus.GaugeVec{} -var noopObserverVec = &noopObserverVector{} // just use a convenience struct for all the no-ops var noop = &noopMetric{} @@ -235,22 +233,3 @@ func (noopMetric) Desc() *prometheus.Desc { return nil } func (noopMetric) Write(*dto.Metric) error { return nil } func (noopMetric) Describe(chan<- *prometheus.Desc) {} func (noopMetric) Collect(chan<- prometheus.Metric) {} - -type noopObserverVector struct{} - -func (noopObserverVector) GetMetricWith(prometheus.Labels) (prometheus.Observer, error) { - return noop, nil -} -func (noopObserverVector) GetMetricWithLabelValues(...string) (prometheus.Observer, error) { - return noop, nil -} -func (noopObserverVector) With(prometheus.Labels) prometheus.Observer { return noop } -func (noopObserverVector) WithLabelValues(...string) prometheus.Observer { return noop } -func (noopObserverVector) CurryWith(prometheus.Labels) (prometheus.ObserverVec, error) { - return noopObserverVec, nil -} -func (noopObserverVector) MustCurryWith(prometheus.Labels) prometheus.ObserverVec { - return noopObserverVec -} -func (noopObserverVector) Describe(chan<- *prometheus.Desc) {} -func (noopObserverVector) Collect(chan<- prometheus.Metric) {} diff --git a/vendor/k8s.io/component-base/metrics/prometheus/slis/metrics.go b/vendor/k8s.io/component-base/metrics/prometheus/slis/metrics.go new file mode 100644 index 0000000000..7fb4a8e064 --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/prometheus/slis/metrics.go @@ -0,0 +1,76 @@ +/* +Copyright 2022 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 slis + +import ( + "context" + k8smetrics "k8s.io/component-base/metrics" +) + +type HealthcheckStatus string + +const ( + Success HealthcheckStatus = "success" + Error HealthcheckStatus = "error" +) + +type HealthcheckType string + +var ( + // healthcheck is a Prometheus Gauge metrics used for recording the results of a k8s healthcheck. + healthcheck = k8smetrics.NewGaugeVec( + &k8smetrics.GaugeOpts{ + Namespace: "kubernetes", + Name: "healthcheck", + Help: "This metric records the result of a single healthcheck.", + StabilityLevel: k8smetrics.ALPHA, + }, + []string{"name", "type"}, + ) + + // healthchecksTotal is a Prometheus Counter metrics used for counting the results of a k8s healthcheck. + healthchecksTotal = k8smetrics.NewCounterVec( + &k8smetrics.CounterOpts{ + Namespace: "kubernetes", + Name: "healthchecks_total", + Help: "This metric records the results of all healthcheck.", + StabilityLevel: k8smetrics.ALPHA, + }, + []string{"name", "type", "status"}, + ) +) + +func Register(registry k8smetrics.KubeRegistry) { + registry.Register(healthcheck) + registry.Register(healthchecksTotal) +} + +func ResetHealthMetrics() { + healthcheck.Reset() + healthchecksTotal.Reset() +} + +func ObserveHealthcheck(ctx context.Context, name string, healthcheckType string, status HealthcheckStatus) error { + if status == Success { + healthcheck.WithContext(ctx).WithLabelValues(name, healthcheckType).Set(1) + } else { + healthcheck.WithContext(ctx).WithLabelValues(name, healthcheckType).Set(0) + } + + healthchecksTotal.WithContext(ctx).WithLabelValues(name, healthcheckType, string(status)).Inc() + return nil +} diff --git a/vendor/k8s.io/component-base/metrics/prometheus/slis/registry.go b/vendor/k8s.io/component-base/metrics/prometheus/slis/registry.go new file mode 100644 index 0000000000..f26340d3ee --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/prometheus/slis/registry.go @@ -0,0 +1,27 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package slis + +import ( + "k8s.io/component-base/metrics" +) + +var ( + // Registry exposes the SLI registry so that additional SLIs can be + // added on a per-component basis. + Registry = metrics.NewKubeRegistry() +) diff --git a/vendor/k8s.io/component-base/metrics/prometheus/slis/routes.go b/vendor/k8s.io/component-base/metrics/prometheus/slis/routes.go new file mode 100644 index 0000000000..4e88b7c24a --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/prometheus/slis/routes.go @@ -0,0 +1,53 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package slis + +import ( + "net/http" + "sync" + + "k8s.io/component-base/metrics" +) + +var ( + installOnce = sync.Once{} + installWithResetOnce = sync.Once{} +) + +type mux interface { + Handle(path string, handler http.Handler) +} + +type SLIMetrics struct{} + +// Install adds the DefaultMetrics handler +func (s SLIMetrics) Install(m mux) { + installOnce.Do(func() { + Register(Registry) + m.Handle("/metrics/slis", metrics.HandlerFor(Registry, metrics.HandlerOpts{})) + }) +} + +type SLIMetricsWithReset struct{} + +// Install adds the DefaultMetrics handler +func (s SLIMetricsWithReset) Install(m mux) { + installWithResetOnce.Do(func() { + Register(Registry) + m.Handle("/metrics/slis", metrics.HandlerWithReset(Registry, metrics.HandlerOpts{})) + }) +} diff --git a/vendor/k8s.io/component-base/metrics/prometheus/workqueue/metrics.go b/vendor/k8s.io/component-base/metrics/prometheus/workqueue/metrics.go new file mode 100644 index 0000000000..59fd1cf6df --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/prometheus/workqueue/metrics.go @@ -0,0 +1,137 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package workqueue + +import ( + "k8s.io/client-go/util/workqueue" + k8smetrics "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +// Package prometheus sets the workqueue DefaultMetricsFactory to produce +// prometheus metrics. To use this package, you just have to import it. + +// Metrics subsystem and keys used by the workqueue. +const ( + WorkQueueSubsystem = "workqueue" + DepthKey = "depth" + AddsKey = "adds_total" + QueueLatencyKey = "queue_duration_seconds" + WorkDurationKey = "work_duration_seconds" + UnfinishedWorkKey = "unfinished_work_seconds" + LongestRunningProcessorKey = "longest_running_processor_seconds" + RetriesKey = "retries_total" +) + +var ( + depth = k8smetrics.NewGaugeVec(&k8smetrics.GaugeOpts{ + Subsystem: WorkQueueSubsystem, + Name: DepthKey, + StabilityLevel: k8smetrics.ALPHA, + Help: "Current depth of workqueue", + }, []string{"name"}) + + adds = k8smetrics.NewCounterVec(&k8smetrics.CounterOpts{ + Subsystem: WorkQueueSubsystem, + Name: AddsKey, + StabilityLevel: k8smetrics.ALPHA, + Help: "Total number of adds handled by workqueue", + }, []string{"name"}) + + latency = k8smetrics.NewHistogramVec(&k8smetrics.HistogramOpts{ + Subsystem: WorkQueueSubsystem, + Name: QueueLatencyKey, + StabilityLevel: k8smetrics.ALPHA, + Help: "How long in seconds an item stays in workqueue before being requested.", + Buckets: k8smetrics.ExponentialBuckets(10e-9, 10, 10), + }, []string{"name"}) + + workDuration = k8smetrics.NewHistogramVec(&k8smetrics.HistogramOpts{ + Subsystem: WorkQueueSubsystem, + Name: WorkDurationKey, + StabilityLevel: k8smetrics.ALPHA, + Help: "How long in seconds processing an item from workqueue takes.", + Buckets: k8smetrics.ExponentialBuckets(10e-9, 10, 10), + }, []string{"name"}) + + unfinished = k8smetrics.NewGaugeVec(&k8smetrics.GaugeOpts{ + Subsystem: WorkQueueSubsystem, + Name: UnfinishedWorkKey, + StabilityLevel: k8smetrics.ALPHA, + Help: "How many seconds of work has done that " + + "is in progress and hasn't been observed by work_duration. Large " + + "values indicate stuck threads. One can deduce the number of stuck " + + "threads by observing the rate at which this increases.", + }, []string{"name"}) + + longestRunningProcessor = k8smetrics.NewGaugeVec(&k8smetrics.GaugeOpts{ + Subsystem: WorkQueueSubsystem, + Name: LongestRunningProcessorKey, + StabilityLevel: k8smetrics.ALPHA, + Help: "How many seconds has the longest running " + + "processor for workqueue been running.", + }, []string{"name"}) + + retries = k8smetrics.NewCounterVec(&k8smetrics.CounterOpts{ + Subsystem: WorkQueueSubsystem, + Name: RetriesKey, + StabilityLevel: k8smetrics.ALPHA, + Help: "Total number of retries handled by workqueue", + }, []string{"name"}) + + metrics = []k8smetrics.Registerable{ + depth, adds, latency, workDuration, unfinished, longestRunningProcessor, retries, + } +) + +type prometheusMetricsProvider struct { +} + +func init() { + for _, m := range metrics { + legacyregistry.MustRegister(m) + } + workqueue.SetProvider(prometheusMetricsProvider{}) +} + +func (prometheusMetricsProvider) NewDepthMetric(name string) workqueue.GaugeMetric { + return depth.WithLabelValues(name) +} + +func (prometheusMetricsProvider) NewAddsMetric(name string) workqueue.CounterMetric { + return adds.WithLabelValues(name) +} + +func (prometheusMetricsProvider) NewLatencyMetric(name string) workqueue.HistogramMetric { + return latency.WithLabelValues(name) +} + +func (prometheusMetricsProvider) NewWorkDurationMetric(name string) workqueue.HistogramMetric { + return workDuration.WithLabelValues(name) +} + +func (prometheusMetricsProvider) NewUnfinishedWorkSecondsMetric(name string) workqueue.SettableGaugeMetric { + return unfinished.WithLabelValues(name) +} + +func (prometheusMetricsProvider) NewLongestRunningProcessorSecondsMetric(name string) workqueue.SettableGaugeMetric { + return longestRunningProcessor.WithLabelValues(name) +} + +func (prometheusMetricsProvider) NewRetriesMetric(name string) workqueue.CounterMetric { + return retries.WithLabelValues(name) +} diff --git a/vendor/k8s.io/component-base/metrics/registry.go b/vendor/k8s.io/component-base/metrics/registry.go index af7d1b8bff..9a7138c11f 100644 --- a/vendor/k8s.io/component-base/metrics/registry.go +++ b/vendor/k8s.io/component-base/metrics/registry.go @@ -157,6 +157,10 @@ type KubeRegistry interface { Reset() // RegisterMetaMetrics registers metrics about the number of registered metrics. RegisterMetaMetrics() + // Registerer exposes the underlying prometheus registerer + Registerer() prometheus.Registerer + // Gatherer exposes the underlying prometheus gatherer + Gatherer() prometheus.Gatherer } // kubeRegistry is a wrapper around a prometheus registry-type object. Upon initialization @@ -188,6 +192,16 @@ func (kr *kubeRegistry) Register(c Registerable) error { return nil } +// Registerer exposes the underlying prometheus.Registerer +func (kr *kubeRegistry) Registerer() prometheus.Registerer { + return kr.PromRegistry +} + +// Gatherer exposes the underlying prometheus.Gatherer +func (kr *kubeRegistry) Gatherer() prometheus.Gatherer { + return kr.PromRegistry +} + // MustRegister works like Register but registers any number of // Collectors and panics upon the first registration that causes an // error. diff --git a/vendor/k8s.io/component-base/metrics/testutil/metrics.go b/vendor/k8s.io/component-base/metrics/testutil/metrics.go new file mode 100644 index 0000000000..df3f8ee0c1 --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/testutil/metrics.go @@ -0,0 +1,435 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testutil + +import ( + "fmt" + "io" + "math" + "reflect" + "sort" + "strings" + + dto "github.com/prometheus/client_model/go" + "github.com/prometheus/common/expfmt" + "github.com/prometheus/common/model" + + "k8s.io/component-base/metrics" +) + +var ( + // MetricNameLabel is label under which model.Sample stores metric name + MetricNameLabel model.LabelName = model.MetricNameLabel + // QuantileLabel is label under which model.Sample stores latency quantile value + QuantileLabel model.LabelName = model.QuantileLabel +) + +// Metrics is generic metrics for other specific metrics +type Metrics map[string]model.Samples + +// Equal returns true if all metrics are the same as the arguments. +func (m *Metrics) Equal(o Metrics) bool { + var leftKeySet []string + var rightKeySet []string + for k := range *m { + leftKeySet = append(leftKeySet, k) + } + for k := range o { + rightKeySet = append(rightKeySet, k) + } + if !reflect.DeepEqual(leftKeySet, rightKeySet) { + return false + } + for _, k := range leftKeySet { + if !(*m)[k].Equal(o[k]) { + return false + } + } + return true +} + +// NewMetrics returns new metrics which are initialized. +func NewMetrics() Metrics { + result := make(Metrics) + return result +} + +// ParseMetrics parses Metrics from data returned from prometheus endpoint +func ParseMetrics(data string, output *Metrics) error { + dec := expfmt.NewDecoder(strings.NewReader(data), expfmt.FmtText) + decoder := expfmt.SampleDecoder{ + Dec: dec, + Opts: &expfmt.DecodeOptions{}, + } + + for { + var v model.Vector + if err := decoder.Decode(&v); err != nil { + if err == io.EOF { + // Expected loop termination condition. + return nil + } + continue + } + for _, metric := range v { + name := string(metric.Metric[MetricNameLabel]) + (*output)[name] = append((*output)[name], metric) + } + } +} + +// TextToMetricFamilies reads 'in' as the simple and flat text-based exchange +// format and creates MetricFamily proto messages. It returns the MetricFamily +// proto messages in a map where the metric names are the keys, along with any +// error encountered. +func TextToMetricFamilies(in io.Reader) (map[string]*dto.MetricFamily, error) { + var textParser expfmt.TextParser + return textParser.TextToMetricFamilies(in) +} + +// PrintSample returns formatted representation of metric Sample +func PrintSample(sample *model.Sample) string { + buf := make([]string, 0) + // Id is a VERY special label. For 'normal' container it's useless, but it's necessary + // for 'system' containers (e.g. /docker-daemon, /kubelet, etc.). We know if that's the + // case by checking if there's a label "kubernetes_container_name" present. It's hacky + // but it works... + _, normalContainer := sample.Metric["kubernetes_container_name"] + for k, v := range sample.Metric { + if strings.HasPrefix(string(k), "__") { + continue + } + + if string(k) == "id" && normalContainer { + continue + } + buf = append(buf, fmt.Sprintf("%v=%v", string(k), v)) + } + return fmt.Sprintf("[%v] = %v", strings.Join(buf, ","), sample.Value) +} + +// ComputeHistogramDelta computes the change in histogram metric for a selected label. +// Results are stored in after samples +func ComputeHistogramDelta(before, after model.Samples, label model.LabelName) { + beforeSamplesMap := make(map[string]*model.Sample) + for _, bSample := range before { + beforeSamplesMap[makeKey(bSample.Metric[label], bSample.Metric["le"])] = bSample + } + for _, aSample := range after { + if bSample, found := beforeSamplesMap[makeKey(aSample.Metric[label], aSample.Metric["le"])]; found { + aSample.Value = aSample.Value - bSample.Value + } + } +} + +func makeKey(a, b model.LabelValue) string { + return string(a) + "___" + string(b) +} + +// GetMetricValuesForLabel returns value of metric for a given dimension +func GetMetricValuesForLabel(ms Metrics, metricName, label string) map[string]int64 { + samples, found := ms[metricName] + result := make(map[string]int64, len(samples)) + if !found { + return result + } + for _, sample := range samples { + count := int64(sample.Value) + dimensionName := string(sample.Metric[model.LabelName(label)]) + result[dimensionName] = count + } + return result +} + +// ValidateMetrics verifies if every sample of metric has all expected labels +func ValidateMetrics(metrics Metrics, metricName string, expectedLabels ...string) error { + samples, ok := metrics[metricName] + if !ok { + return fmt.Errorf("metric %q was not found in metrics", metricName) + } + for _, sample := range samples { + for _, l := range expectedLabels { + if _, ok := sample.Metric[model.LabelName(l)]; !ok { + return fmt.Errorf("metric %q is missing label %q, sample: %q", metricName, l, sample.String()) + } + } + } + return nil +} + +// Histogram wraps prometheus histogram DTO (data transfer object) +type Histogram struct { + *dto.Histogram +} + +// HistogramVec wraps a slice of Histogram. +// Note that each Histogram must have the same number of buckets. +type HistogramVec []*Histogram + +// GetAggregatedSampleCount aggregates the sample count of each inner Histogram. +func (vec HistogramVec) GetAggregatedSampleCount() uint64 { + var count uint64 + for _, hist := range vec { + count += hist.GetSampleCount() + } + return count +} + +// GetAggregatedSampleSum aggregates the sample sum of each inner Histogram. +func (vec HistogramVec) GetAggregatedSampleSum() float64 { + var sum float64 + for _, hist := range vec { + sum += hist.GetSampleSum() + } + return sum +} + +// Quantile first aggregates inner buckets of each Histogram, and then +// computes q-th quantile of a cumulative histogram. +func (vec HistogramVec) Quantile(q float64) float64 { + var buckets []bucket + + for i, hist := range vec { + for j, bckt := range hist.Bucket { + if i == 0 { + buckets = append(buckets, bucket{ + count: float64(bckt.GetCumulativeCount()), + upperBound: bckt.GetUpperBound(), + }) + } else { + buckets[j].count += float64(bckt.GetCumulativeCount()) + } + } + } + + if len(buckets) == 0 || buckets[len(buckets)-1].upperBound != math.Inf(+1) { + // The list of buckets in dto.Histogram doesn't include the final +Inf bucket, so we + // add it here for the rest of the samples. + buckets = append(buckets, bucket{ + count: float64(vec.GetAggregatedSampleCount()), + upperBound: math.Inf(+1), + }) + } + + return bucketQuantile(q, buckets) +} + +// Average computes wrapped histograms' average value. +func (vec HistogramVec) Average() float64 { + return vec.GetAggregatedSampleSum() / float64(vec.GetAggregatedSampleCount()) +} + +// Validate makes sure the wrapped histograms have all necessary fields set and with valid values. +func (vec HistogramVec) Validate() error { + bucketSize := 0 + for i, hist := range vec { + if err := hist.Validate(); err != nil { + return err + } + if i == 0 { + bucketSize = len(hist.GetBucket()) + } else if bucketSize != len(hist.GetBucket()) { + return fmt.Errorf("found different bucket size: expect %v, but got %v at index %v", bucketSize, len(hist.GetBucket()), i) + } + } + return nil +} + +// GetHistogramVecFromGatherer collects a metric, that matches the input labelValue map, +// from a gatherer implementing k8s.io/component-base/metrics.Gatherer interface. +// Used only for testing purposes where we need to gather metrics directly from a running binary (without metrics endpoint). +func GetHistogramVecFromGatherer(gatherer metrics.Gatherer, metricName string, lvMap map[string]string) (HistogramVec, error) { + var metricFamily *dto.MetricFamily + m, err := gatherer.Gather() + if err != nil { + return nil, err + } + for _, mFamily := range m { + if mFamily.GetName() == metricName { + metricFamily = mFamily + break + } + } + + if metricFamily == nil { + return nil, fmt.Errorf("metric %q not found", metricName) + } + + if len(metricFamily.GetMetric()) == 0 { + return nil, fmt.Errorf("metric %q is empty", metricName) + } + + vec := make(HistogramVec, 0) + for _, metric := range metricFamily.GetMetric() { + if LabelsMatch(metric, lvMap) { + if hist := metric.GetHistogram(); hist != nil { + vec = append(vec, &Histogram{hist}) + } + } + } + return vec, nil +} + +func uint64Ptr(u uint64) *uint64 { + return &u +} + +// Bucket of a histogram +type bucket struct { + upperBound float64 + count float64 +} + +func bucketQuantile(q float64, buckets []bucket) float64 { + if q < 0 { + return math.Inf(-1) + } + if q > 1 { + return math.Inf(+1) + } + + if len(buckets) < 2 { + return math.NaN() + } + + rank := q * buckets[len(buckets)-1].count + b := sort.Search(len(buckets)-1, func(i int) bool { return buckets[i].count >= rank }) + + if b == 0 { + return buckets[0].upperBound * (rank / buckets[0].count) + } + + if b == len(buckets)-1 && math.IsInf(buckets[b].upperBound, 1) { + return buckets[len(buckets)-2].upperBound + } + + // linear approximation of b-th bucket + brank := rank - buckets[b-1].count + bSize := buckets[b].upperBound - buckets[b-1].upperBound + bCount := buckets[b].count - buckets[b-1].count + + return buckets[b-1].upperBound + bSize*(brank/bCount) +} + +// Quantile computes q-th quantile of a cumulative histogram. +// It's expected the histogram is valid (by calling Validate) +func (hist *Histogram) Quantile(q float64) float64 { + var buckets []bucket + + for _, bckt := range hist.Bucket { + buckets = append(buckets, bucket{ + count: float64(bckt.GetCumulativeCount()), + upperBound: bckt.GetUpperBound(), + }) + } + + if len(buckets) == 0 || buckets[len(buckets)-1].upperBound != math.Inf(+1) { + // The list of buckets in dto.Histogram doesn't include the final +Inf bucket, so we + // add it here for the rest of the samples. + buckets = append(buckets, bucket{ + count: float64(hist.GetSampleCount()), + upperBound: math.Inf(+1), + }) + } + + return bucketQuantile(q, buckets) +} + +// Average computes histogram's average value +func (hist *Histogram) Average() float64 { + return hist.GetSampleSum() / float64(hist.GetSampleCount()) +} + +// Validate makes sure the wrapped histogram has all necessary fields set and with valid values. +func (hist *Histogram) Validate() error { + if hist.SampleCount == nil || hist.GetSampleCount() == 0 { + return fmt.Errorf("nil or empty histogram SampleCount") + } + + if hist.SampleSum == nil || hist.GetSampleSum() == 0 { + return fmt.Errorf("nil or empty histogram SampleSum") + } + + for _, bckt := range hist.Bucket { + if bckt == nil { + return fmt.Errorf("empty histogram bucket") + } + if bckt.UpperBound == nil || bckt.GetUpperBound() < 0 { + return fmt.Errorf("nil or negative histogram bucket UpperBound") + } + } + + return nil +} + +// GetGaugeMetricValue extracts metric value from GaugeMetric +func GetGaugeMetricValue(m metrics.GaugeMetric) (float64, error) { + metricProto := &dto.Metric{} + if err := m.Write(metricProto); err != nil { + return 0, fmt.Errorf("error writing m: %v", err) + } + return metricProto.Gauge.GetValue(), nil +} + +// GetCounterMetricValue extracts metric value from CounterMetric +func GetCounterMetricValue(m metrics.CounterMetric) (float64, error) { + metricProto := &dto.Metric{} + if err := m.(metrics.Metric).Write(metricProto); err != nil { + return 0, fmt.Errorf("error writing m: %v", err) + } + return metricProto.Counter.GetValue(), nil +} + +// GetHistogramMetricValue extracts sum of all samples from ObserverMetric +func GetHistogramMetricValue(m metrics.ObserverMetric) (float64, error) { + metricProto := &dto.Metric{} + if err := m.(metrics.Metric).Write(metricProto); err != nil { + return 0, fmt.Errorf("error writing m: %v", err) + } + return metricProto.Histogram.GetSampleSum(), nil +} + +// GetHistogramMetricCount extracts count of all samples from ObserverMetric +func GetHistogramMetricCount(m metrics.ObserverMetric) (uint64, error) { + metricProto := &dto.Metric{} + if err := m.(metrics.Metric).Write(metricProto); err != nil { + return 0, fmt.Errorf("error writing m: %v", err) + } + return metricProto.Histogram.GetSampleCount(), nil +} + +// LabelsMatch returns true if metric has all expected labels otherwise false +func LabelsMatch(metric *dto.Metric, labelFilter map[string]string) bool { + metricLabels := map[string]string{} + + for _, labelPair := range metric.Label { + metricLabels[labelPair.GetName()] = labelPair.GetValue() + } + + // length comparison then match key to values in the maps + if len(labelFilter) > len(metricLabels) { + return false + } + + for labelName, labelValue := range labelFilter { + if value, ok := metricLabels[labelName]; !ok || value != labelValue { + return false + } + } + + return true +} diff --git a/vendor/k8s.io/component-base/metrics/testutil/promlint.go b/vendor/k8s.io/component-base/metrics/testutil/promlint.go new file mode 100644 index 0000000000..4c537be225 --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/testutil/promlint.go @@ -0,0 +1,151 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testutil + +import ( + "fmt" + "io" + "strings" + + "github.com/prometheus/client_golang/prometheus/testutil/promlint" +) + +// exceptionMetrics is an exception list of metrics which violates promlint rules. +// +// The original entries come from the existing metrics when we introduce promlint. +// We setup this list for allow and not fail on the current violations. +// Generally speaking, you need to fix the problem for a new metric rather than add it into the list. +var exceptionMetrics = []string{ + // k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/server/egressselector + "apiserver_egress_dialer_dial_failure_count", // counter metrics should have "_total" suffix + + // k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/server/healthz + "apiserver_request_total", // label names should be written in 'snake_case' not 'camelCase' + + // k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/endpoints/filters + "authenticated_user_requests", // counter metrics should have "_total" suffix + "authentication_attempts", // counter metrics should have "_total" suffix + + // kube-apiserver + "aggregator_openapi_v2_regeneration_count", + "apiserver_admission_step_admission_duration_seconds_summary", + "apiserver_current_inflight_requests", + "apiserver_longrunning_gauge", + "get_token_count", + "get_token_fail_count", + "ssh_tunnel_open_count", + "ssh_tunnel_open_fail_count", + + // kube-controller-manager + "attachdetach_controller_forced_detaches", + "authenticated_user_requests", + "authentication_attempts", + "get_token_count", + "get_token_fail_count", + "node_collector_evictions_number", +} + +// A Problem is an issue detected by a Linter. +type Problem promlint.Problem + +func (p *Problem) String() string { + return fmt.Sprintf("%s:%s", p.Metric, p.Text) +} + +// A Linter is a Prometheus metrics linter. It identifies issues with metric +// names, types, and metadata, and reports them to the caller. +type Linter struct { + promLinter *promlint.Linter +} + +// Lint performs a linting pass, returning a slice of Problems indicating any +// issues found in the metrics stream. The slice is sorted by metric name +// and issue description. +func (l *Linter) Lint() ([]Problem, error) { + promProblems, err := l.promLinter.Lint() + if err != nil { + return nil, err + } + + // Ignore problems those in exception list + problems := make([]Problem, 0, len(promProblems)) + for i := range promProblems { + if !l.shouldIgnore(promProblems[i].Metric) { + problems = append(problems, Problem(promProblems[i])) + } + } + + return problems, nil +} + +// shouldIgnore returns true if metric in the exception list, otherwise returns false. +func (l *Linter) shouldIgnore(metricName string) bool { + for i := range exceptionMetrics { + if metricName == exceptionMetrics[i] { + return true + } + } + + return false +} + +// NewPromLinter creates a new Linter that reads an input stream of Prometheus metrics. +// Only the text exposition format is supported. +func NewPromLinter(r io.Reader) *Linter { + return &Linter{ + promLinter: promlint.New(r), + } +} + +func mergeProblems(problems []Problem) string { + var problemsMsg []string + + for index := range problems { + problemsMsg = append(problemsMsg, problems[index].String()) + } + + return strings.Join(problemsMsg, ",") +} + +// shouldIgnore returns true if metric in the exception list, otherwise returns false. +func shouldIgnore(metricName string) bool { + for i := range exceptionMetrics { + if metricName == exceptionMetrics[i] { + return true + } + } + + return false +} + +// getLintError will ignore the metrics in exception list and converts lint problem to error. +func getLintError(problems []promlint.Problem) error { + var filteredProblems []Problem + for _, problem := range problems { + if shouldIgnore(problem.Metric) { + continue + } + + filteredProblems = append(filteredProblems, Problem(problem)) + } + + if len(filteredProblems) == 0 { + return nil + } + + return fmt.Errorf("lint error: %s", mergeProblems(filteredProblems)) +} diff --git a/vendor/k8s.io/component-base/metrics/testutil/testutil.go b/vendor/k8s.io/component-base/metrics/testutil/testutil.go new file mode 100644 index 0000000000..8587c75224 --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/testutil/testutil.go @@ -0,0 +1,93 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testutil + +import ( + "fmt" + "io" + + "github.com/prometheus/client_golang/prometheus/testutil" + + apimachineryversion "k8s.io/apimachinery/pkg/version" + "k8s.io/component-base/metrics" +) + +// CollectAndCompare registers the provided Collector with a newly created +// pedantic Registry. It then does the same as GatherAndCompare, gathering the +// metrics from the pedantic Registry. +func CollectAndCompare(c metrics.Collector, expected io.Reader, metricNames ...string) error { + lintProblems, err := testutil.CollectAndLint(c, metricNames...) + if err != nil { + return err + } + if err := getLintError(lintProblems); err != nil { + return err + } + + return testutil.CollectAndCompare(c, expected, metricNames...) +} + +// GatherAndCompare gathers all metrics from the provided Gatherer and compares +// it to an expected output read from the provided Reader in the Prometheus text +// exposition format. If any metricNames are provided, only metrics with those +// names are compared. +func GatherAndCompare(g metrics.Gatherer, expected io.Reader, metricNames ...string) error { + lintProblems, err := testutil.GatherAndLint(g, metricNames...) + if err != nil { + return err + } + if err := getLintError(lintProblems); err != nil { + return err + } + + return testutil.GatherAndCompare(g, expected, metricNames...) +} + +// CustomCollectAndCompare registers the provided StableCollector with a newly created +// registry. It then does the same as GatherAndCompare, gathering the +// metrics from the pedantic Registry. +func CustomCollectAndCompare(c metrics.StableCollector, expected io.Reader, metricNames ...string) error { + registry := metrics.NewKubeRegistry() + registry.CustomMustRegister(c) + + return GatherAndCompare(registry, expected, metricNames...) +} + +// ScrapeAndCompare calls a remote exporter's endpoint which is expected to return some metrics in +// plain text format. Then it compares it with the results that the `expected` would return. +// If the `metricNames` is not empty it would filter the comparison only to the given metric names. +func ScrapeAndCompare(url string, expected io.Reader, metricNames ...string) error { + return testutil.ScrapeAndCompare(url, expected, metricNames...) +} + +// NewFakeKubeRegistry creates a fake `KubeRegistry` that takes the input version as `build in version`. +// It should only be used in testing scenario especially for the deprecated metrics. +// The input version format should be `major.minor.patch`, e.g. '1.18.0'. +func NewFakeKubeRegistry(ver string) metrics.KubeRegistry { + backup := metrics.BuildVersion + defer func() { + metrics.BuildVersion = backup + }() + + metrics.BuildVersion = func() apimachineryversion.Info { + return apimachineryversion.Info{ + GitVersion: fmt.Sprintf("v%s-alpha+1.12345", ver), + } + } + + return metrics.NewKubeRegistry() +} diff --git a/vendor/k8s.io/component-base/metrics/value.go b/vendor/k8s.io/component-base/metrics/value.go index b525bb602a..4a405048cf 100644 --- a/vendor/k8s.io/component-base/metrics/value.go +++ b/vendor/k8s.io/component-base/metrics/value.go @@ -60,8 +60,7 @@ func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues // NewLazyMetricWithTimestamp is a helper of NewMetricWithTimestamp. // // Warning: the Metric 'm' must be the one created by NewLazyConstMetric(), -// -// otherwise, no stability guarantees would be offered. +// otherwise, no stability guarantees would be offered. func NewLazyMetricWithTimestamp(t time.Time, m Metric) Metric { if m == nil { return nil diff --git a/vendor/k8s.io/component-helpers/node/util/hostname.go b/vendor/k8s.io/component-helpers/node/util/hostname.go new file mode 100644 index 0000000000..15d62c0ba5 --- /dev/null +++ b/vendor/k8s.io/component-helpers/node/util/hostname.go @@ -0,0 +1,46 @@ +/* +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 util + +import ( + "fmt" + "os" + "strings" +) + +// GetHostname returns OS's hostname if 'hostnameOverride' is empty; otherwise, it returns +// 'hostnameOverride'. In either case, the value is canonicalized (trimmed and +// lowercased). +func GetHostname(hostnameOverride string) (string, error) { + hostName := hostnameOverride + if len(hostName) == 0 { + nodeName, err := os.Hostname() + if err != nil { + return "", fmt.Errorf("couldn't determine hostname: %w", err) + } + hostName = nodeName + } + + // Trim whitespaces first to avoid getting an empty hostname + // For linux, the hostname is read from file /proc/sys/kernel/hostname directly + hostName = strings.TrimSpace(hostName) + if len(hostName) == 0 { + return "", fmt.Errorf("empty hostname is invalid") + } + + return strings.ToLower(hostName), nil +} diff --git a/vendor/k8s.io/component-helpers/node/util/ips.go b/vendor/k8s.io/component-helpers/node/util/ips.go new file mode 100644 index 0000000000..ff306a3dc3 --- /dev/null +++ b/vendor/k8s.io/component-helpers/node/util/ips.go @@ -0,0 +1,82 @@ +/* +Copyright 2023 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 ( + "fmt" + "net" + "strings" + + "k8s.io/klog/v2" + netutils "k8s.io/utils/net" +) + +const ( + cloudProviderNone = "" + cloudProviderExternal = "external" +) + +// parseNodeIP implements ParseNodeIPArgument and ParseNodeIPAnnotation +func parseNodeIP(nodeIP string, allowDual, sloppy bool) ([]net.IP, error) { + var nodeIPs []net.IP + if nodeIP != "" || !sloppy { + for _, ip := range strings.Split(nodeIP, ",") { + if sloppy { + ip = strings.TrimSpace(ip) + } + parsedNodeIP := netutils.ParseIPSloppy(ip) + if parsedNodeIP == nil { + if sloppy { + klog.InfoS("Could not parse node IP. Ignoring", "IP", ip) + } else { + return nil, fmt.Errorf("could not parse %q", ip) + } + } else { + nodeIPs = append(nodeIPs, parsedNodeIP) + } + } + } + + if len(nodeIPs) > 2 || (len(nodeIPs) == 2 && netutils.IsIPv6(nodeIPs[0]) == netutils.IsIPv6(nodeIPs[1])) { + return nil, fmt.Errorf("must contain either a single IP or a dual-stack pair of IPs") + } else if len(nodeIPs) == 2 && !allowDual { + return nil, fmt.Errorf("dual-stack not supported in this configuration") + } else if len(nodeIPs) == 2 && (nodeIPs[0].IsUnspecified() || nodeIPs[1].IsUnspecified()) { + return nil, fmt.Errorf("dual-stack node IP cannot include '0.0.0.0' or '::'") + } + + return nodeIPs, nil +} + +// ParseNodeIPArgument parses kubelet's --node-ip argument. If nodeIP contains invalid +// values, they will be logged and ignored. Dual-stack node IPs are allowed if +// cloudProvider is unset, or if it is `"external"` and allowCloudDualStack is true. +func ParseNodeIPArgument(nodeIP, cloudProvider string, allowCloudDualStack bool) ([]net.IP, error) { + var allowDualStack bool + if (cloudProvider == cloudProviderNone) || (cloudProvider == cloudProviderExternal && allowCloudDualStack) { + allowDualStack = true + } + return parseNodeIP(nodeIP, allowDualStack, true) +} + +// ParseNodeIPAnnotation parses the `alpha.kubernetes.io/provided-node-ip` annotation, +// which can be either a single IP address or (if allowDualStack is true) a +// comma-separated pair of IP addresses. Unlike with ParseNodeIPArgument, invalid values +// are considered an error. +func ParseNodeIPAnnotation(nodeIP string, allowDualStack bool) ([]net.IP, error) { + return parseNodeIP(nodeIP, allowDualStack, false) +} diff --git a/vendor/k8s.io/controller-manager/LICENSE b/vendor/k8s.io/controller-manager/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/vendor/k8s.io/controller-manager/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/k8s.io/controller-manager/config/OWNERS b/vendor/k8s.io/controller-manager/config/OWNERS new file mode 100644 index 0000000000..200d01f74c --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/OWNERS @@ -0,0 +1,14 @@ +approvers: + - api-approvers + - deads2k + - luxas + - mtaufen + - sttts +reviewers: + - api-reviewers + - deads2k + - luxas + - mtaufen + - sttts +emeritus_approvers: + - stewart-yu diff --git a/vendor/k8s.io/controller-manager/config/doc.go b/vendor/k8s.io/controller-manager/config/doc.go new file mode 100644 index 0000000000..a98a0c8cd8 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package + +package config // import "k8s.io/controller-manager/config" diff --git a/vendor/k8s.io/controller-manager/config/register.go b/vendor/k8s.io/controller-manager/config/register.go new file mode 100644 index 0000000000..1f1a4a3c68 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/register.go @@ -0,0 +1,46 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the "group" that is needed to uniquely identify the API +const GroupName = "controllermanager.config.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal} + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package, + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &LeaderMigrationConfiguration{}, + ) + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/types.go b/vendor/k8s.io/controller-manager/config/types.go new file mode 100644 index 0000000000..e8d2470eea --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/types.go @@ -0,0 +1,82 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package config should only include generic configurations +package config + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + componentbaseconfig "k8s.io/component-base/config" +) + +// GenericControllerManagerConfiguration holds configuration for a generic controller-manager +type GenericControllerManagerConfiguration struct { + // port is the port that the controller-manager's http service runs on. + Port int32 + // address is the IP address to serve on (set to 0.0.0.0 for all interfaces). + Address string + // minResyncPeriod is the resync period in reflectors; will be random between + // minResyncPeriod and 2*minResyncPeriod. + MinResyncPeriod metav1.Duration + // ClientConnection specifies the kubeconfig file and client connection + // settings for the proxy server to use when communicating with the apiserver. + ClientConnection componentbaseconfig.ClientConnectionConfiguration + // How long to wait between starting controller managers + ControllerStartInterval metav1.Duration + // leaderElection defines the configuration of leader election client. + LeaderElection componentbaseconfig.LeaderElectionConfiguration + // Controllers is the list of controllers to enable or disable + // '*' means "all enabled by default controllers" + // 'foo' means "enable 'foo'" + // '-foo' means "disable 'foo'" + // first item for a particular name wins + Controllers []string + // DebuggingConfiguration holds configuration for Debugging related features. + Debugging componentbaseconfig.DebuggingConfiguration + // LeaderMigrationEnabled indicates whether Leader Migration should be enabled for the controller manager. + LeaderMigrationEnabled bool + // LeaderMigration holds the configuration for Leader Migration. + LeaderMigration LeaderMigrationConfiguration +} + +// LeaderMigrationConfiguration provides versioned configuration for all migrating leader locks. +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type LeaderMigrationConfiguration struct { + metav1.TypeMeta + + // LeaderName is the name of the leader election resource that protects the migration + // E.g. 1-20-KCM-to-1-21-CCM + LeaderName string + + // ResourceLock indicates the resource object type that will be used to lock + // Should be "leases" or "endpoints" + ResourceLock string + + // ControllerLeaders contains a list of migrating leader lock configurations + ControllerLeaders []ControllerLeaderConfiguration +} + +// ControllerLeaderConfiguration provides the configuration for a migrating leader lock. +type ControllerLeaderConfiguration struct { + // Name is the name of the controller being migrated + // E.g. service-controller, route-controller, cloud-node-controller, etc + Name string + + // Component is the name of the component in which the controller should be running. + // E.g. kube-controller-manager, cloud-controller-manager, etc + // Or '*' meaning the controller can be run under any component that participates in the migration + Component string +} diff --git a/vendor/k8s.io/controller-manager/config/v1/conversion.go b/vendor/k8s.io/controller-manager/config/v1/conversion.go new file mode 100644 index 0000000000..4ba5bd8a8c --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1/conversion.go @@ -0,0 +1,82 @@ +/* +Copyright 2022 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 v1 + +import ( + "unsafe" + + "k8s.io/apimachinery/pkg/conversion" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/controller-manager/config" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +const ResourceLockLeases = "leases" + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*ControllerLeaderConfiguration)(nil), (*config.ControllerLeaderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(a.(*ControllerLeaderConfiguration), b.(*config.ControllerLeaderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.ControllerLeaderConfiguration)(nil), (*ControllerLeaderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_ControllerLeaderConfiguration_To_v1_ControllerLeaderConfiguration(a.(*config.ControllerLeaderConfiguration), b.(*ControllerLeaderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LeaderMigrationConfiguration)(nil), (*config.LeaderMigrationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(a.(*LeaderMigrationConfiguration), b.(*config.LeaderMigrationConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.LeaderMigrationConfiguration)(nil), (*LeaderMigrationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_LeaderMigrationConfiguration_To_v1_LeaderMigrationConfiguration(a.(*config.LeaderMigrationConfiguration), b.(*LeaderMigrationConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func Convert_config_LeaderMigrationConfiguration_To_v1_LeaderMigrationConfiguration(in *config.LeaderMigrationConfiguration, out *LeaderMigrationConfiguration, s conversion.Scope) error { + out.LeaderName = in.LeaderName + out.ControllerLeaders = *(*[]ControllerLeaderConfiguration)(unsafe.Pointer(&in.ControllerLeaders)) + return nil +} + +func Convert_v1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(in *LeaderMigrationConfiguration, out *config.LeaderMigrationConfiguration, s conversion.Scope) error { + out.LeaderName = in.LeaderName + out.ControllerLeaders = *(*[]config.ControllerLeaderConfiguration)(unsafe.Pointer(&in.ControllerLeaders)) + out.ResourceLock = ResourceLockLeases + return nil +} + +func Convert_v1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(in *ControllerLeaderConfiguration, out *config.ControllerLeaderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.Component = in.Component + return nil +} + +func Convert_config_ControllerLeaderConfiguration_To_v1_ControllerLeaderConfiguration(in *config.ControllerLeaderConfiguration, out *ControllerLeaderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.Component = in.Component + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/v1/doc.go b/vendor/k8s.io/controller-manager/config/v1/doc.go new file mode 100644 index 0000000000..037cfb7856 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2022 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. +*/ + +// +k8s:deepcopy-gen=package +// +groupName=controllermanager.config.k8s.io + +package v1 // import "k8s.io/controller-manager/config/v1" diff --git a/vendor/k8s.io/controller-manager/config/v1/register.go b/vendor/k8s.io/controller-manager/config/v1/register.go new file mode 100644 index 0000000000..e48f90a7c8 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1/register.go @@ -0,0 +1,48 @@ +/* +Copyright 2022 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 v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the "group" that is needed to uniquely identify the API +const GroupName = "controllermanager.config.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"} + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package, + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &LeaderMigrationConfiguration{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/v1/types.go b/vendor/k8s.io/controller-manager/config/v1/types.go new file mode 100644 index 0000000000..e202786862 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1/types.go @@ -0,0 +1,47 @@ +/* +Copyright 2022 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 v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// LeaderMigrationConfiguration provides versioned configuration for all migrating leader locks. +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type LeaderMigrationConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // LeaderName is the name of the leader election resource that protects the migration + // E.g. 1-20-KCM-to-1-21-CCM + LeaderName string `json:"leaderName"` + + // ControllerLeaders contains a list of migrating leader lock configurations + // +listType=atomic + ControllerLeaders []ControllerLeaderConfiguration `json:"controllerLeaders"` +} + +// ControllerLeaderConfiguration provides the configuration for a migrating leader lock. +type ControllerLeaderConfiguration struct { + // Name is the name of the controller being migrated + // E.g. service-controller, route-controller, cloud-node-controller, etc + Name string `json:"name"` + + // Component is the name of the component in which the controller should be running. + // E.g. kube-controller-manager, cloud-controller-manager, etc + // Or '*' meaning the controller can be run under any component that participates in the migration + Component string `json:"component"` +} diff --git a/vendor/k8s.io/controller-manager/config/v1/zz_generated.deepcopy.go b/vendor/k8s.io/controller-manager/config/v1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..d5b54b0b23 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1/zz_generated.deepcopy.go @@ -0,0 +1,72 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 deepcopy-gen. DO NOT EDIT. + +package v1 + +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 *ControllerLeaderConfiguration) DeepCopyInto(out *ControllerLeaderConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerLeaderConfiguration. +func (in *ControllerLeaderConfiguration) DeepCopy() *ControllerLeaderConfiguration { + if in == nil { + return nil + } + out := new(ControllerLeaderConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaderMigrationConfiguration) DeepCopyInto(out *LeaderMigrationConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.ControllerLeaders != nil { + in, out := &in.ControllerLeaders, &out.ControllerLeaders + *out = make([]ControllerLeaderConfiguration, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaderMigrationConfiguration. +func (in *LeaderMigrationConfiguration) DeepCopy() *LeaderMigrationConfiguration { + if in == nil { + return nil + } + out := new(LeaderMigrationConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LeaderMigrationConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/v1alpha1/conversion.go b/vendor/k8s.io/controller-manager/config/v1alpha1/conversion.go new file mode 100644 index 0000000000..d006429e7f --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1alpha1/conversion.go @@ -0,0 +1,39 @@ +/* +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 v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/conversion" + cmconfig "k8s.io/controller-manager/config" +) + +// Important! The public back-and-forth conversion functions for the types in this generic +// package with ComponentConfig types need to be manually exposed like this in order for +// other packages that reference this package to be able to call these conversion functions +// in an autogenerated manner. +// TODO: Fix the bug in conversion-gen so it automatically discovers these Convert_* functions +// in autogenerated code as well. + +// Convert_v1alpha1_GenericControllerManagerConfiguration_To_config_GenericControllerManagerConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_GenericControllerManagerConfiguration_To_config_GenericControllerManagerConfiguration(in *GenericControllerManagerConfiguration, out *cmconfig.GenericControllerManagerConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_GenericControllerManagerConfiguration_To_config_GenericControllerManagerConfiguration(in, out, s) +} + +// Convert_config_GenericControllerManagerConfiguration_To_v1alpha1_GenericControllerManagerConfiguration is an autogenerated conversion function. +func Convert_config_GenericControllerManagerConfiguration_To_v1alpha1_GenericControllerManagerConfiguration(in *cmconfig.GenericControllerManagerConfiguration, out *GenericControllerManagerConfiguration, s conversion.Scope) error { + return autoConvert_config_GenericControllerManagerConfiguration_To_v1alpha1_GenericControllerManagerConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/controller-manager/config/v1alpha1/defaults.go b/vendor/k8s.io/controller-manager/config/v1alpha1/defaults.go new file mode 100644 index 0000000000..82a920c706 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1alpha1/defaults.go @@ -0,0 +1,51 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1" +) + +func RecommendedDefaultGenericControllerManagerConfiguration(obj *GenericControllerManagerConfiguration) { + zero := metav1.Duration{} + if obj.Address == "" { + obj.Address = "0.0.0.0" + } + if obj.MinResyncPeriod == zero { + obj.MinResyncPeriod = metav1.Duration{Duration: 12 * time.Hour} + } + if obj.ControllerStartInterval == zero { + obj.ControllerStartInterval = metav1.Duration{Duration: 0 * time.Second} + } + if len(obj.Controllers) == 0 { + obj.Controllers = []string{"*"} + } + + if len(obj.LeaderElection.ResourceLock) == 0 { + // Use lease-based leader election to reduce cost. + // We migrated for EndpointsLease lock in 1.17 and starting in 1.20 we + // migrated to Lease lock. + obj.LeaderElection.ResourceLock = "leases" + } + + // Use the default ClientConnectionConfiguration and LeaderElectionConfiguration options + componentbaseconfigv1alpha1.RecommendedDefaultClientConnectionConfiguration(&obj.ClientConnection) + componentbaseconfigv1alpha1.RecommendedDefaultLeaderElectionConfiguration(&obj.LeaderElection) +} diff --git a/vendor/k8s.io/controller-manager/config/v1alpha1/doc.go b/vendor/k8s.io/controller-manager/config/v1alpha1/doc.go new file mode 100644 index 0000000000..b01cf385dd --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1alpha1/doc.go @@ -0,0 +1,23 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=k8s.io/controller-manager/config +// +k8s:conversion-gen=k8s.io/controller-manager/config/v1alpha1 +// +k8s:openapi-gen=true +// +groupName=controllermanager.config.k8s.io + +package v1alpha1 // import "k8s.io/controller-manager/config/v1alpha1" diff --git a/vendor/k8s.io/controller-manager/config/v1alpha1/register.go b/vendor/k8s.io/controller-manager/config/v1alpha1/register.go new file mode 100644 index 0000000000..59603396d6 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1alpha1/register.go @@ -0,0 +1,48 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the "group" that is needed to uniquely identify the API +const GroupName = "controllermanager.config.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package, + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &LeaderMigrationConfiguration{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/v1alpha1/types.go b/vendor/k8s.io/controller-manager/config/v1alpha1/types.go new file mode 100644 index 0000000000..9cd9eee9c6 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1alpha1/types.go @@ -0,0 +1,81 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1" +) + +// GenericControllerManagerConfiguration holds configuration for a generic controller-manager. +type GenericControllerManagerConfiguration struct { + // port is the port that the controller-manager's http service runs on. + Port int32 + // address is the IP address to serve on (set to 0.0.0.0 for all interfaces). + Address string + // minResyncPeriod is the resync period in reflectors; will be random between + // minResyncPeriod and 2*minResyncPeriod. + MinResyncPeriod metav1.Duration + // ClientConnection specifies the kubeconfig file and client connection + // settings for the proxy server to use when communicating with the apiserver. + ClientConnection componentbaseconfigv1alpha1.ClientConnectionConfiguration + // How long to wait between starting controller managers + ControllerStartInterval metav1.Duration + // leaderElection defines the configuration of leader election client. + LeaderElection componentbaseconfigv1alpha1.LeaderElectionConfiguration + // Controllers is the list of controllers to enable or disable + // '*' means "all enabled by default controllers" + // 'foo' means "enable 'foo'" + // '-foo' means "disable 'foo'" + // first item for a particular name wins + Controllers []string + // DebuggingConfiguration holds configuration for Debugging related features. + Debugging componentbaseconfigv1alpha1.DebuggingConfiguration + // LeaderMigrationEnabled indicates whether Leader Migration should be enabled for the controller manager. + LeaderMigrationEnabled bool + // LeaderMigration holds the configuration for Leader Migration. + LeaderMigration LeaderMigrationConfiguration +} + +// LeaderMigrationConfiguration provides versioned configuration for all migrating leader locks. +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type LeaderMigrationConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // LeaderName is the name of the leader election resource that protects the migration + // E.g. 1-20-KCM-to-1-21-CCM + LeaderName string `json:"leaderName"` + + // ResourceLock indicates the resource object type that will be used to lock + // Should be "leases" or "endpoints" + ResourceLock string `json:"resourceLock"` + + // ControllerLeaders contains a list of migrating leader lock configurations + ControllerLeaders []ControllerLeaderConfiguration `json:"controllerLeaders"` +} + +// ControllerLeaderConfiguration provides the configuration for a migrating leader lock. +type ControllerLeaderConfiguration struct { + // Name is the name of the controller being migrated + // E.g. service-controller, route-controller, cloud-node-controller, etc + Name string `json:"name"` + + // Component is the name of the component in which the controller should be running. + // E.g. kube-controller-manager, cloud-controller-manager, etc + // Or '*' meaning the controller can be run under any component that participates in the migration + Component string `json:"component"` +} diff --git a/vendor/k8s.io/controller-manager/config/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/controller-manager/config/v1alpha1/zz_generated.conversion.go new file mode 100644 index 0000000000..40da2f91df --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1alpha1/zz_generated.conversion.go @@ -0,0 +1,161 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 conversion-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + unsafe "unsafe" + + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + configv1alpha1 "k8s.io/component-base/config/v1alpha1" + config "k8s.io/controller-manager/config" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*ControllerLeaderConfiguration)(nil), (*config.ControllerLeaderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(a.(*ControllerLeaderConfiguration), b.(*config.ControllerLeaderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.ControllerLeaderConfiguration)(nil), (*ControllerLeaderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_ControllerLeaderConfiguration_To_v1alpha1_ControllerLeaderConfiguration(a.(*config.ControllerLeaderConfiguration), b.(*ControllerLeaderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LeaderMigrationConfiguration)(nil), (*config.LeaderMigrationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(a.(*LeaderMigrationConfiguration), b.(*config.LeaderMigrationConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.LeaderMigrationConfiguration)(nil), (*LeaderMigrationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_LeaderMigrationConfiguration_To_v1alpha1_LeaderMigrationConfiguration(a.(*config.LeaderMigrationConfiguration), b.(*LeaderMigrationConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*config.GenericControllerManagerConfiguration)(nil), (*GenericControllerManagerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_GenericControllerManagerConfiguration_To_v1alpha1_GenericControllerManagerConfiguration(a.(*config.GenericControllerManagerConfiguration), b.(*GenericControllerManagerConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*GenericControllerManagerConfiguration)(nil), (*config.GenericControllerManagerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_GenericControllerManagerConfiguration_To_config_GenericControllerManagerConfiguration(a.(*GenericControllerManagerConfiguration), b.(*config.GenericControllerManagerConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(in *ControllerLeaderConfiguration, out *config.ControllerLeaderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.Component = in.Component + return nil +} + +// Convert_v1alpha1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(in *ControllerLeaderConfiguration, out *config.ControllerLeaderConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(in, out, s) +} + +func autoConvert_config_ControllerLeaderConfiguration_To_v1alpha1_ControllerLeaderConfiguration(in *config.ControllerLeaderConfiguration, out *ControllerLeaderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.Component = in.Component + return nil +} + +// Convert_config_ControllerLeaderConfiguration_To_v1alpha1_ControllerLeaderConfiguration is an autogenerated conversion function. +func Convert_config_ControllerLeaderConfiguration_To_v1alpha1_ControllerLeaderConfiguration(in *config.ControllerLeaderConfiguration, out *ControllerLeaderConfiguration, s conversion.Scope) error { + return autoConvert_config_ControllerLeaderConfiguration_To_v1alpha1_ControllerLeaderConfiguration(in, out, s) +} + +func autoConvert_v1alpha1_GenericControllerManagerConfiguration_To_config_GenericControllerManagerConfiguration(in *GenericControllerManagerConfiguration, out *config.GenericControllerManagerConfiguration, s conversion.Scope) error { + out.Port = in.Port + out.Address = in.Address + out.MinResyncPeriod = in.MinResyncPeriod + if err := configv1alpha1.Convert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil { + return err + } + out.ControllerStartInterval = in.ControllerStartInterval + if err := configv1alpha1.Convert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(&in.LeaderElection, &out.LeaderElection, s); err != nil { + return err + } + out.Controllers = *(*[]string)(unsafe.Pointer(&in.Controllers)) + if err := configv1alpha1.Convert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(&in.Debugging, &out.Debugging, s); err != nil { + return err + } + out.LeaderMigrationEnabled = in.LeaderMigrationEnabled + if err := Convert_v1alpha1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(&in.LeaderMigration, &out.LeaderMigration, s); err != nil { + return err + } + return nil +} + +func autoConvert_config_GenericControllerManagerConfiguration_To_v1alpha1_GenericControllerManagerConfiguration(in *config.GenericControllerManagerConfiguration, out *GenericControllerManagerConfiguration, s conversion.Scope) error { + out.Port = in.Port + out.Address = in.Address + out.MinResyncPeriod = in.MinResyncPeriod + if err := configv1alpha1.Convert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil { + return err + } + out.ControllerStartInterval = in.ControllerStartInterval + if err := configv1alpha1.Convert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(&in.LeaderElection, &out.LeaderElection, s); err != nil { + return err + } + out.Controllers = *(*[]string)(unsafe.Pointer(&in.Controllers)) + if err := configv1alpha1.Convert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(&in.Debugging, &out.Debugging, s); err != nil { + return err + } + out.LeaderMigrationEnabled = in.LeaderMigrationEnabled + if err := Convert_config_LeaderMigrationConfiguration_To_v1alpha1_LeaderMigrationConfiguration(&in.LeaderMigration, &out.LeaderMigration, s); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(in *LeaderMigrationConfiguration, out *config.LeaderMigrationConfiguration, s conversion.Scope) error { + out.LeaderName = in.LeaderName + out.ResourceLock = in.ResourceLock + out.ControllerLeaders = *(*[]config.ControllerLeaderConfiguration)(unsafe.Pointer(&in.ControllerLeaders)) + return nil +} + +// Convert_v1alpha1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(in *LeaderMigrationConfiguration, out *config.LeaderMigrationConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(in, out, s) +} + +func autoConvert_config_LeaderMigrationConfiguration_To_v1alpha1_LeaderMigrationConfiguration(in *config.LeaderMigrationConfiguration, out *LeaderMigrationConfiguration, s conversion.Scope) error { + out.LeaderName = in.LeaderName + out.ResourceLock = in.ResourceLock + out.ControllerLeaders = *(*[]ControllerLeaderConfiguration)(unsafe.Pointer(&in.ControllerLeaders)) + return nil +} + +// Convert_config_LeaderMigrationConfiguration_To_v1alpha1_LeaderMigrationConfiguration is an autogenerated conversion function. +func Convert_config_LeaderMigrationConfiguration_To_v1alpha1_LeaderMigrationConfiguration(in *config.LeaderMigrationConfiguration, out *LeaderMigrationConfiguration, s conversion.Scope) error { + return autoConvert_config_LeaderMigrationConfiguration_To_v1alpha1_LeaderMigrationConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/controller-manager/config/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/controller-manager/config/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..5d0eea2474 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,99 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +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 *ControllerLeaderConfiguration) DeepCopyInto(out *ControllerLeaderConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerLeaderConfiguration. +func (in *ControllerLeaderConfiguration) DeepCopy() *ControllerLeaderConfiguration { + if in == nil { + return nil + } + out := new(ControllerLeaderConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GenericControllerManagerConfiguration) DeepCopyInto(out *GenericControllerManagerConfiguration) { + *out = *in + out.MinResyncPeriod = in.MinResyncPeriod + out.ClientConnection = in.ClientConnection + out.ControllerStartInterval = in.ControllerStartInterval + in.LeaderElection.DeepCopyInto(&out.LeaderElection) + if in.Controllers != nil { + in, out := &in.Controllers, &out.Controllers + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.Debugging.DeepCopyInto(&out.Debugging) + in.LeaderMigration.DeepCopyInto(&out.LeaderMigration) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericControllerManagerConfiguration. +func (in *GenericControllerManagerConfiguration) DeepCopy() *GenericControllerManagerConfiguration { + if in == nil { + return nil + } + out := new(GenericControllerManagerConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaderMigrationConfiguration) DeepCopyInto(out *LeaderMigrationConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.ControllerLeaders != nil { + in, out := &in.ControllerLeaders, &out.ControllerLeaders + *out = make([]ControllerLeaderConfiguration, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaderMigrationConfiguration. +func (in *LeaderMigrationConfiguration) DeepCopy() *LeaderMigrationConfiguration { + if in == nil { + return nil + } + out := new(LeaderMigrationConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LeaderMigrationConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/v1beta1/doc.go b/vendor/k8s.io/controller-manager/config/v1beta1/doc.go new file mode 100644 index 0000000000..94cd3f1283 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1beta1/doc.go @@ -0,0 +1,22 @@ +/* +Copyright 2021 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. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=k8s.io/controller-manager/config +// +k8s:openapi-gen=true +// +groupName=controllermanager.config.k8s.io + +package v1beta1 // import "k8s.io/controller-manager/config/v1beta1" diff --git a/vendor/k8s.io/controller-manager/config/v1beta1/register.go b/vendor/k8s.io/controller-manager/config/v1beta1/register.go new file mode 100644 index 0000000000..c812dcd3be --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1beta1/register.go @@ -0,0 +1,48 @@ +/* +Copyright 2021 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 ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the "group" that is needed to uniquely identify the API +const GroupName = "controllermanager.config.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"} + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package, + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &LeaderMigrationConfiguration{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/v1beta1/types.go b/vendor/k8s.io/controller-manager/config/v1beta1/types.go new file mode 100644 index 0000000000..91467c006b --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1beta1/types.go @@ -0,0 +1,51 @@ +/* +Copyright 2021 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 ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// LeaderMigrationConfiguration provides versioned configuration for all migrating leader locks. +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type LeaderMigrationConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // LeaderName is the name of the leader election resource that protects the migration + // E.g. 1-20-KCM-to-1-21-CCM + LeaderName string `json:"leaderName"` + + // ResourceLock indicates the resource object type that will be used to lock + // Should be "leases" or "endpoints" + ResourceLock string `json:"resourceLock"` + + // ControllerLeaders contains a list of migrating leader lock configurations + // +listType=atomic + ControllerLeaders []ControllerLeaderConfiguration `json:"controllerLeaders"` +} + +// ControllerLeaderConfiguration provides the configuration for a migrating leader lock. +type ControllerLeaderConfiguration struct { + // Name is the name of the controller being migrated + // E.g. service-controller, route-controller, cloud-node-controller, etc + Name string `json:"name"` + + // Component is the name of the component in which the controller should be running. + // E.g. kube-controller-manager, cloud-controller-manager, etc + // Or '*' meaning the controller can be run under any component that participates in the migration + Component string `json:"component"` +} diff --git a/vendor/k8s.io/controller-manager/config/v1beta1/zz_generated.conversion.go b/vendor/k8s.io/controller-manager/config/v1beta1/zz_generated.conversion.go new file mode 100644 index 0000000000..37a6330850 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1beta1/zz_generated.conversion.go @@ -0,0 +1,106 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 conversion-gen. DO NOT EDIT. + +package v1beta1 + +import ( + unsafe "unsafe" + + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + config "k8s.io/controller-manager/config" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*ControllerLeaderConfiguration)(nil), (*config.ControllerLeaderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(a.(*ControllerLeaderConfiguration), b.(*config.ControllerLeaderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.ControllerLeaderConfiguration)(nil), (*ControllerLeaderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_ControllerLeaderConfiguration_To_v1beta1_ControllerLeaderConfiguration(a.(*config.ControllerLeaderConfiguration), b.(*ControllerLeaderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LeaderMigrationConfiguration)(nil), (*config.LeaderMigrationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(a.(*LeaderMigrationConfiguration), b.(*config.LeaderMigrationConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.LeaderMigrationConfiguration)(nil), (*LeaderMigrationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_LeaderMigrationConfiguration_To_v1beta1_LeaderMigrationConfiguration(a.(*config.LeaderMigrationConfiguration), b.(*LeaderMigrationConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1beta1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(in *ControllerLeaderConfiguration, out *config.ControllerLeaderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.Component = in.Component + return nil +} + +// Convert_v1beta1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration is an autogenerated conversion function. +func Convert_v1beta1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(in *ControllerLeaderConfiguration, out *config.ControllerLeaderConfiguration, s conversion.Scope) error { + return autoConvert_v1beta1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(in, out, s) +} + +func autoConvert_config_ControllerLeaderConfiguration_To_v1beta1_ControllerLeaderConfiguration(in *config.ControllerLeaderConfiguration, out *ControllerLeaderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.Component = in.Component + return nil +} + +// Convert_config_ControllerLeaderConfiguration_To_v1beta1_ControllerLeaderConfiguration is an autogenerated conversion function. +func Convert_config_ControllerLeaderConfiguration_To_v1beta1_ControllerLeaderConfiguration(in *config.ControllerLeaderConfiguration, out *ControllerLeaderConfiguration, s conversion.Scope) error { + return autoConvert_config_ControllerLeaderConfiguration_To_v1beta1_ControllerLeaderConfiguration(in, out, s) +} + +func autoConvert_v1beta1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(in *LeaderMigrationConfiguration, out *config.LeaderMigrationConfiguration, s conversion.Scope) error { + out.LeaderName = in.LeaderName + out.ResourceLock = in.ResourceLock + out.ControllerLeaders = *(*[]config.ControllerLeaderConfiguration)(unsafe.Pointer(&in.ControllerLeaders)) + return nil +} + +// Convert_v1beta1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration is an autogenerated conversion function. +func Convert_v1beta1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(in *LeaderMigrationConfiguration, out *config.LeaderMigrationConfiguration, s conversion.Scope) error { + return autoConvert_v1beta1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(in, out, s) +} + +func autoConvert_config_LeaderMigrationConfiguration_To_v1beta1_LeaderMigrationConfiguration(in *config.LeaderMigrationConfiguration, out *LeaderMigrationConfiguration, s conversion.Scope) error { + out.LeaderName = in.LeaderName + out.ResourceLock = in.ResourceLock + out.ControllerLeaders = *(*[]ControllerLeaderConfiguration)(unsafe.Pointer(&in.ControllerLeaders)) + return nil +} + +// Convert_config_LeaderMigrationConfiguration_To_v1beta1_LeaderMigrationConfiguration is an autogenerated conversion function. +func Convert_config_LeaderMigrationConfiguration_To_v1beta1_LeaderMigrationConfiguration(in *config.LeaderMigrationConfiguration, out *LeaderMigrationConfiguration, s conversion.Scope) error { + return autoConvert_config_LeaderMigrationConfiguration_To_v1beta1_LeaderMigrationConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/controller-manager/config/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/controller-manager/config/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..8285edb9fc --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,72 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 deepcopy-gen. DO NOT EDIT. + +package v1beta1 + +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 *ControllerLeaderConfiguration) DeepCopyInto(out *ControllerLeaderConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerLeaderConfiguration. +func (in *ControllerLeaderConfiguration) DeepCopy() *ControllerLeaderConfiguration { + if in == nil { + return nil + } + out := new(ControllerLeaderConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaderMigrationConfiguration) DeepCopyInto(out *LeaderMigrationConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.ControllerLeaders != nil { + in, out := &in.ControllerLeaders, &out.ControllerLeaders + *out = make([]ControllerLeaderConfiguration, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaderMigrationConfiguration. +func (in *LeaderMigrationConfiguration) DeepCopy() *LeaderMigrationConfiguration { + if in == nil { + return nil + } + out := new(LeaderMigrationConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LeaderMigrationConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/zz_generated.deepcopy.go b/vendor/k8s.io/controller-manager/config/zz_generated.deepcopy.go new file mode 100644 index 0000000000..00cd420880 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/zz_generated.deepcopy.go @@ -0,0 +1,99 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +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 deepcopy-gen. DO NOT EDIT. + +package config + +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 *ControllerLeaderConfiguration) DeepCopyInto(out *ControllerLeaderConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerLeaderConfiguration. +func (in *ControllerLeaderConfiguration) DeepCopy() *ControllerLeaderConfiguration { + if in == nil { + return nil + } + out := new(ControllerLeaderConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GenericControllerManagerConfiguration) DeepCopyInto(out *GenericControllerManagerConfiguration) { + *out = *in + out.MinResyncPeriod = in.MinResyncPeriod + out.ClientConnection = in.ClientConnection + out.ControllerStartInterval = in.ControllerStartInterval + out.LeaderElection = in.LeaderElection + if in.Controllers != nil { + in, out := &in.Controllers, &out.Controllers + *out = make([]string, len(*in)) + copy(*out, *in) + } + out.Debugging = in.Debugging + in.LeaderMigration.DeepCopyInto(&out.LeaderMigration) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericControllerManagerConfiguration. +func (in *GenericControllerManagerConfiguration) DeepCopy() *GenericControllerManagerConfiguration { + if in == nil { + return nil + } + out := new(GenericControllerManagerConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaderMigrationConfiguration) DeepCopyInto(out *LeaderMigrationConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.ControllerLeaders != nil { + in, out := &in.ControllerLeaders, &out.ControllerLeaders + *out = make([]ControllerLeaderConfiguration, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaderMigrationConfiguration. +func (in *LeaderMigrationConfiguration) DeepCopy() *LeaderMigrationConfiguration { + if in == nil { + return nil + } + out := new(LeaderMigrationConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LeaderMigrationConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/vendor/k8s.io/controller-manager/options/debugging.go b/vendor/k8s.io/controller-manager/options/debugging.go new file mode 100644 index 0000000000..063186a506 --- /dev/null +++ b/vendor/k8s.io/controller-manager/options/debugging.go @@ -0,0 +1,72 @@ +/* +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 + +import ( + "github.com/spf13/pflag" + + componentbaseconfig "k8s.io/component-base/config" +) + +// DebuggingOptions holds the Debugging options. +type DebuggingOptions struct { + *componentbaseconfig.DebuggingConfiguration +} + +// RecommendedDebuggingOptions returns the currently recommended debugging options. These are subject to change +// between releases as we add options and decide which features should be exposed or not by default. +func RecommendedDebuggingOptions() *DebuggingOptions { + return &DebuggingOptions{ + DebuggingConfiguration: &componentbaseconfig.DebuggingConfiguration{ + EnableProfiling: true, // profile debugging is cheap to have exposed and standard on kube binaries + }, + } +} + +// AddFlags adds flags related to debugging for controller manager to the specified FlagSet. +func (o *DebuggingOptions) AddFlags(fs *pflag.FlagSet) { + if o == nil { + return + } + + fs.BoolVar(&o.EnableProfiling, "profiling", o.EnableProfiling, + "Enable profiling via web interface host:port/debug/pprof/") + fs.BoolVar(&o.EnableContentionProfiling, "contention-profiling", o.EnableContentionProfiling, + "Enable block profiling, if profiling is enabled") +} + +// ApplyTo fills up Debugging config with options. +func (o *DebuggingOptions) ApplyTo(cfg *componentbaseconfig.DebuggingConfiguration) error { + if o == nil { + return nil + } + + cfg.EnableProfiling = o.EnableProfiling + cfg.EnableContentionProfiling = o.EnableContentionProfiling + + return nil +} + +// Validate checks validation of DebuggingOptions. +func (o *DebuggingOptions) Validate() []error { + if o == nil { + return nil + } + + errs := []error{} + return errs +} diff --git a/vendor/k8s.io/controller-manager/options/generic.go b/vendor/k8s.io/controller-manager/options/generic.go new file mode 100644 index 0000000000..45c086b11f --- /dev/null +++ b/vendor/k8s.io/controller-manager/options/generic.go @@ -0,0 +1,123 @@ +/* +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 + +import ( + "fmt" + "strings" + + "k8s.io/apimachinery/pkg/util/sets" + cliflag "k8s.io/component-base/cli/flag" + "k8s.io/component-base/config/options" + cmconfig "k8s.io/controller-manager/config" + migration "k8s.io/controller-manager/pkg/leadermigration/options" +) + +// GenericControllerManagerConfigurationOptions holds the options which are generic. +type GenericControllerManagerConfigurationOptions struct { + *cmconfig.GenericControllerManagerConfiguration + Debugging *DebuggingOptions + // LeaderMigration is the options for leader migration, a nil indicates default options should be applied. + LeaderMigration *migration.LeaderMigrationOptions +} + +// NewGenericControllerManagerConfigurationOptions returns generic configuration default values for both +// the kube-controller-manager and the cloud-contoller-manager. Any common changes should +// be made here. Any individual changes should be made in that controller. +func NewGenericControllerManagerConfigurationOptions(cfg *cmconfig.GenericControllerManagerConfiguration) *GenericControllerManagerConfigurationOptions { + o := &GenericControllerManagerConfigurationOptions{ + GenericControllerManagerConfiguration: cfg, + Debugging: RecommendedDebuggingOptions(), + LeaderMigration: &migration.LeaderMigrationOptions{}, + } + + return o +} + +// AddFlags adds flags related to generic for controller manager to the specified FlagSet. +func (o *GenericControllerManagerConfigurationOptions) AddFlags(fss *cliflag.NamedFlagSets, allControllers, disabledByDefaultControllers []string) { + if o == nil { + return + } + + o.Debugging.AddFlags(fss.FlagSet("debugging")) + o.LeaderMigration.AddFlags(fss.FlagSet("leader-migration")) + genericfs := fss.FlagSet("generic") + genericfs.DurationVar(&o.MinResyncPeriod.Duration, "min-resync-period", o.MinResyncPeriod.Duration, "The resync period in reflectors will be random between MinResyncPeriod and 2*MinResyncPeriod.") + genericfs.StringVar(&o.ClientConnection.ContentType, "kube-api-content-type", o.ClientConnection.ContentType, "Content type of requests sent to apiserver.") + genericfs.Float32Var(&o.ClientConnection.QPS, "kube-api-qps", o.ClientConnection.QPS, "QPS to use while talking with kubernetes apiserver.") + genericfs.Int32Var(&o.ClientConnection.Burst, "kube-api-burst", o.ClientConnection.Burst, "Burst to use while talking with kubernetes apiserver.") + genericfs.DurationVar(&o.ControllerStartInterval.Duration, "controller-start-interval", o.ControllerStartInterval.Duration, "Interval between starting controller managers.") + genericfs.StringSliceVar(&o.Controllers, "controllers", o.Controllers, fmt.Sprintf(""+ + "A list of controllers to enable. '*' enables all on-by-default controllers, 'foo' enables the controller "+ + "named 'foo', '-foo' disables the controller named 'foo'.\nAll controllers: %s\nDisabled-by-default controllers: %s", + strings.Join(allControllers, ", "), strings.Join(disabledByDefaultControllers, ", "))) + + options.BindLeaderElectionFlags(&o.LeaderElection, genericfs) +} + +// ApplyTo fills up generic config with options. +func (o *GenericControllerManagerConfigurationOptions) ApplyTo(cfg *cmconfig.GenericControllerManagerConfiguration) error { + if o == nil { + return nil + } + + if err := o.Debugging.ApplyTo(&cfg.Debugging); err != nil { + return err + } + if err := o.LeaderMigration.ApplyTo(cfg); err != nil { + return err + } + cfg.Port = o.Port + cfg.Address = o.Address + cfg.MinResyncPeriod = o.MinResyncPeriod + cfg.ClientConnection = o.ClientConnection + cfg.ControllerStartInterval = o.ControllerStartInterval + cfg.LeaderElection = o.LeaderElection + cfg.Controllers = o.Controllers + + return nil +} + +// Validate checks validation of GenericOptions. +func (o *GenericControllerManagerConfigurationOptions) Validate(allControllers []string, disabledByDefaultControllers []string) []error { + if o == nil { + return nil + } + + errs := []error{} + errs = append(errs, o.Debugging.Validate()...) + + // TODO: This can be removed when ResourceLock is not available + // Lock the ResourceLock using leases + if o.LeaderElection.LeaderElect && o.LeaderElection.ResourceLock != "leases" { + errs = append(errs, fmt.Errorf(`resourceLock value must be "leases"`)) + } + + allControllersSet := sets.NewString(allControllers...) + for _, controller := range o.Controllers { + if controller == "*" { + continue + } + controller = strings.TrimPrefix(controller, "-") + if !allControllersSet.Has(controller) { + errs = append(errs, fmt.Errorf("%q is not in the list of known controllers", controller)) + } + } + + return errs +} diff --git a/vendor/k8s.io/controller-manager/pkg/clientbuilder/client_builder.go b/vendor/k8s.io/controller-manager/pkg/clientbuilder/client_builder.go new file mode 100644 index 0000000000..2908474837 --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/clientbuilder/client_builder.go @@ -0,0 +1,102 @@ +/* +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 clientbuilder + +import ( + "k8s.io/client-go/discovery" + clientset "k8s.io/client-go/kubernetes" + restclient "k8s.io/client-go/rest" + "k8s.io/klog/v2" +) + +// ControllerClientBuilder allows you to get clients and configs for controllers +// Please note a copy also exists in staging/src/k8s.io/cloud-provider/cloud.go +// TODO: Extract this into a separate controller utilities repo (issues/68947) +type ControllerClientBuilder interface { + Config(name string) (*restclient.Config, error) + ConfigOrDie(name string) *restclient.Config + Client(name string) (clientset.Interface, error) + ClientOrDie(name string) clientset.Interface + DiscoveryClient(name string) (discovery.DiscoveryInterface, error) + DiscoveryClientOrDie(name string) discovery.DiscoveryInterface +} + +// SimpleControllerClientBuilder returns a fixed client with different user agents +type SimpleControllerClientBuilder struct { + // ClientConfig is a skeleton config to clone and use as the basis for each controller client + ClientConfig *restclient.Config +} + +// Config returns a client config for a fixed client +func (b SimpleControllerClientBuilder) Config(name string) (*restclient.Config, error) { + clientConfig := *b.ClientConfig + return restclient.AddUserAgent(&clientConfig, name), nil +} + +// ConfigOrDie returns a client config if no error from previous config func. +// If it gets an error getting the client, it will log the error and kill the process it's running in. +func (b SimpleControllerClientBuilder) ConfigOrDie(name string) *restclient.Config { + clientConfig, err := b.Config(name) + if err != nil { + klog.Fatal(err) + } + return clientConfig +} + +// Client returns a clientset.Interface built from the ClientBuilder +func (b SimpleControllerClientBuilder) Client(name string) (clientset.Interface, error) { + clientConfig, err := b.Config(name) + if err != nil { + return nil, err + } + return clientset.NewForConfig(clientConfig) +} + +// ClientOrDie returns a clientset.interface built from the ClientBuilder with no error. +// If it gets an error getting the client, it will log the error and kill the process it's running in. +func (b SimpleControllerClientBuilder) ClientOrDie(name string) clientset.Interface { + client, err := b.Client(name) + if err != nil { + klog.Fatal(err) + } + return client +} + +// DiscoveryClient returns a discovery.DiscoveryInterface built from the ClientBuilder +// Discovery is special because it will artificially pump the burst quite high to handle the many discovery requests. +func (b SimpleControllerClientBuilder) DiscoveryClient(name string) (discovery.DiscoveryInterface, error) { + clientConfig, err := b.Config(name) + if err != nil { + return nil, err + } + // Discovery makes a lot of requests infrequently. This allows the burst to succeed and refill to happen + // in just a few seconds. + clientConfig.Burst = 200 + clientConfig.QPS = 20 + return clientset.NewForConfig(clientConfig) +} + +// DiscoveryClientOrDie returns a discovery.DiscoveryInterface built from the ClientBuilder with no error. +// Discovery is special because it will artificially pump the burst quite high to handle the many discovery requests. +// If it gets an error getting the client, it will log the error and kill the process it's running in. +func (b SimpleControllerClientBuilder) DiscoveryClientOrDie(name string) discovery.DiscoveryInterface { + client, err := b.DiscoveryClient(name) + if err != nil { + klog.Fatal(err) + } + return client +} diff --git a/vendor/k8s.io/controller-manager/pkg/clientbuilder/client_builder_dynamic.go b/vendor/k8s.io/controller-manager/pkg/clientbuilder/client_builder_dynamic.go new file mode 100644 index 0000000000..514bb1b837 --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/clientbuilder/client_builder_dynamic.go @@ -0,0 +1,271 @@ +/* +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 clientbuilder + +import ( + "context" + "fmt" + "net/http" + "sync" + "time" + + "golang.org/x/oauth2" + v1authenticationapi "k8s.io/api/authentication/v1" + v1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + apiserverserviceaccount "k8s.io/apiserver/pkg/authentication/serviceaccount" + "k8s.io/client-go/discovery" + clientset "k8s.io/client-go/kubernetes" + v1core "k8s.io/client-go/kubernetes/typed/core/v1" + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/transport" + "k8s.io/klog/v2" + "k8s.io/utils/clock" + utilpointer "k8s.io/utils/pointer" +) + +var ( + // defaultExpirationSeconds defines the duration of a TokenRequest in seconds. + defaultExpirationSeconds = int64(3600) + // defaultLeewayPercent defines the percentage of expiration left before the client trigger a token rotation. + // range[0, 100] + defaultLeewayPercent = 20 +) + +type DynamicControllerClientBuilder struct { + // ClientConfig is a skeleton config to clone and use as the basis for each controller client + ClientConfig *restclient.Config + + // CoreClient is used to provision service accounts if needed and watch for their associated tokens + // to construct a controller client + CoreClient v1core.CoreV1Interface + + // Namespace is the namespace used to host the service accounts that will back the + // controllers. It must be highly privileged namespace which normal users cannot inspect. + Namespace string + + // roundTripperFuncMap is a cache stores the corresponding roundtripper func for each + // service account + roundTripperFuncMap map[string]func(http.RoundTripper) http.RoundTripper + + // expirationSeconds defines the token expiration seconds + expirationSeconds int64 + + // leewayPercent defines the percentage of expiration left before the client trigger a token rotation. + leewayPercent int + + mutex sync.Mutex + + clock clock.Clock +} + +// NewDynamicClientBuilder returns client builder which uses TokenRequest feature and refresh service account token periodically +func NewDynamicClientBuilder(clientConfig *restclient.Config, coreClient v1core.CoreV1Interface, ns string) ControllerClientBuilder { + builder := &DynamicControllerClientBuilder{ + ClientConfig: clientConfig, + CoreClient: coreClient, + Namespace: ns, + roundTripperFuncMap: map[string]func(http.RoundTripper) http.RoundTripper{}, + expirationSeconds: defaultExpirationSeconds, + leewayPercent: defaultLeewayPercent, + clock: clock.RealClock{}, + } + return builder +} + +// this function only for test purpose, don't call it +func NewTestDynamicClientBuilder(clientConfig *restclient.Config, coreClient v1core.CoreV1Interface, ns string, expirationSeconds int64, leewayPercent int) ControllerClientBuilder { + builder := &DynamicControllerClientBuilder{ + ClientConfig: clientConfig, + CoreClient: coreClient, + Namespace: ns, + roundTripperFuncMap: map[string]func(http.RoundTripper) http.RoundTripper{}, + expirationSeconds: expirationSeconds, + leewayPercent: leewayPercent, + clock: clock.RealClock{}, + } + return builder +} + +func (t *DynamicControllerClientBuilder) Config(saName string) (*restclient.Config, error) { + _, err := getOrCreateServiceAccount(t.CoreClient, t.Namespace, saName) + if err != nil { + return nil, err + } + + configCopy := constructClient(t.Namespace, saName, t.ClientConfig) + + t.mutex.Lock() + defer t.mutex.Unlock() + + rt, ok := t.roundTripperFuncMap[saName] + if ok { + configCopy.Wrap(rt) + } else { + cachedTokenSource := transport.NewCachedTokenSource(&tokenSourceImpl{ + namespace: t.Namespace, + serviceAccountName: saName, + coreClient: t.CoreClient, + expirationSeconds: t.expirationSeconds, + leewayPercent: t.leewayPercent, + }) + configCopy.Wrap(transport.ResettableTokenSourceWrapTransport(cachedTokenSource)) + t.roundTripperFuncMap[saName] = configCopy.WrapTransport + } + + return &configCopy, nil +} + +func (t *DynamicControllerClientBuilder) ConfigOrDie(name string) *restclient.Config { + clientConfig, err := t.Config(name) + if err != nil { + klog.Fatal(err) + } + return clientConfig +} + +func (t *DynamicControllerClientBuilder) Client(name string) (clientset.Interface, error) { + clientConfig, err := t.Config(name) + if err != nil { + return nil, err + } + return clientset.NewForConfig(clientConfig) +} + +func (t *DynamicControllerClientBuilder) ClientOrDie(name string) clientset.Interface { + client, err := t.Client(name) + if err != nil { + klog.Fatal(err) + } + return client +} + +func (t *DynamicControllerClientBuilder) DiscoveryClient(name string) (discovery.DiscoveryInterface, error) { + clientConfig, err := t.Config(name) + if err != nil { + return nil, err + } + // Discovery makes a lot of requests infrequently. This allows the burst to succeed and refill to happen + // in just a few seconds. + clientConfig.Burst = 200 + clientConfig.QPS = 20 + return clientset.NewForConfig(clientConfig) +} + +func (t *DynamicControllerClientBuilder) DiscoveryClientOrDie(name string) discovery.DiscoveryInterface { + client, err := t.DiscoveryClient(name) + if err != nil { + klog.Fatal(err) + } + return client +} + +type tokenSourceImpl struct { + namespace string + serviceAccountName string + coreClient v1core.CoreV1Interface + expirationSeconds int64 + leewayPercent int +} + +func (ts *tokenSourceImpl) Token() (*oauth2.Token, error) { + var retTokenRequest *v1authenticationapi.TokenRequest + + backoff := wait.Backoff{ + Duration: 500 * time.Millisecond, + Factor: 2, // double the timeout for every failure + Steps: 4, + } + if err := wait.ExponentialBackoff(backoff, func() (bool, error) { + if _, inErr := getOrCreateServiceAccount(ts.coreClient, ts.namespace, ts.serviceAccountName); inErr != nil { + klog.Warningf("get or create service account failed: %v", inErr) + return false, nil + } + + tr, inErr := ts.coreClient.ServiceAccounts(ts.namespace).CreateToken(context.TODO(), ts.serviceAccountName, &v1authenticationapi.TokenRequest{ + Spec: v1authenticationapi.TokenRequestSpec{ + ExpirationSeconds: utilpointer.Int64Ptr(ts.expirationSeconds), + }, + }, metav1.CreateOptions{}) + if inErr != nil { + klog.Warningf("get token failed: %v", inErr) + return false, nil + } + retTokenRequest = tr + return true, nil + }); err != nil { + return nil, fmt.Errorf("failed to get token for %s/%s: %v", ts.namespace, ts.serviceAccountName, err) + } + + if retTokenRequest.Spec.ExpirationSeconds == nil { + return nil, fmt.Errorf("nil pointer of expiration in token request") + } + + lifetime := retTokenRequest.Status.ExpirationTimestamp.Time.Sub(time.Now()) + if lifetime < time.Minute*10 { + // possible clock skew issue, pin to minimum token lifetime + lifetime = time.Minute * 10 + } + + leeway := time.Duration(int64(lifetime) * int64(ts.leewayPercent) / 100) + expiry := time.Now().Add(lifetime).Add(-1 * leeway) + + return &oauth2.Token{ + AccessToken: retTokenRequest.Status.Token, + TokenType: "Bearer", + Expiry: expiry, + }, nil +} + +func constructClient(saNamespace, saName string, config *restclient.Config) restclient.Config { + username := apiserverserviceaccount.MakeUsername(saNamespace, saName) + // make a shallow copy + // the caller already castrated the config during creation + // this allows for potential extensions in the future + // for example it preserve HTTP wrappers for custom behavior per request + ret := *config + restclient.AddUserAgent(&ret, username) + return ret +} + +func getOrCreateServiceAccount(coreClient v1core.CoreV1Interface, namespace, name string) (*v1.ServiceAccount, error) { + sa, err := coreClient.ServiceAccounts(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + if err == nil { + return sa, nil + } + if !apierrors.IsNotFound(err) { + return nil, err + } + + // Create the namespace if we can't verify it exists. + // Tolerate errors, since we don't know whether this component has namespace creation permissions. + if _, err := coreClient.Namespaces().Get(context.TODO(), namespace, metav1.GetOptions{}); apierrors.IsNotFound(err) { + if _, err = coreClient.Namespaces().Create(context.TODO(), &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}, metav1.CreateOptions{}); err != nil && !apierrors.IsAlreadyExists(err) { + klog.Warningf("create non-exist namespace %s failed:%v", namespace, err) + } + } + + // Create the service account + sa, err = coreClient.ServiceAccounts(namespace).Create(context.TODO(), &v1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: name}}, metav1.CreateOptions{}) + if apierrors.IsAlreadyExists(err) { + // If we're racing to init and someone else already created it, re-fetch + return coreClient.ServiceAccounts(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + } + return sa, err +} diff --git a/vendor/k8s.io/controller-manager/pkg/features/OWNERS b/vendor/k8s.io/controller-manager/pkg/features/OWNERS new file mode 100644 index 0000000000..3e1dd9f081 --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/features/OWNERS @@ -0,0 +1,4 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - feature-approvers diff --git a/vendor/k8s.io/controller-manager/pkg/features/kube_features.go b/vendor/k8s.io/controller-manager/pkg/features/kube_features.go new file mode 100644 index 0000000000..8864be325e --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/features/kube_features.go @@ -0,0 +1,67 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package features + +import ( + "k8s.io/component-base/featuregate" +) + +const ( + // Every feature gate should add method here following this template: + // + // // owner: @username + // // alpha: v1.4 + // MyFeature featuregate.Feature = "MyFeature" + // + // Feature gates should be listed in alphabetical, case-sensitive + // (upper before any lower case character) order. This reduces the risk + // of code conflicts because changes are more likely to be scattered + // across the file. + + // owner: @nckturner + // kep: http://kep.k8s.io/2699 + // alpha: v1.27 + // Enable webhook in cloud controller manager + CloudControllerManagerWebhook featuregate.Feature = "CloudControllerManagerWebhook" + + // owner: @danwinship + // alpha: v1.27 + // + // Enables dual-stack values in the + // `alpha.kubernetes.io/provided-node-ip` annotation + CloudDualStackNodeIPs featuregate.Feature = "CloudDualStackNodeIPs" + + // owner: @alexanderConstantinescu + // kep: http://kep.k8s.io/3458 + // beta: v1.27 + // + // Enables less load balancer re-configurations by the service controller + // (KCCM) as an effect of changing node state. + StableLoadBalancerNodeSet featuregate.Feature = "StableLoadBalancerNodeSet" +) + +func SetupCurrentKubernetesSpecificFeatureGates(featuregates featuregate.MutableFeatureGate) error { + return featuregates.Add(cloudPublicFeatureGates) +} + +// cloudPublicFeatureGates consists of cloud-specific feature keys. +// To add a new feature, define a key for it at k8s.io/api/pkg/features and add it here. +var cloudPublicFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ + CloudControllerManagerWebhook: {Default: false, PreRelease: featuregate.Alpha}, + CloudDualStackNodeIPs: {Default: false, PreRelease: featuregate.Alpha}, + StableLoadBalancerNodeSet: {Default: true, PreRelease: featuregate.Beta}, +} diff --git a/vendor/k8s.io/controller-manager/pkg/features/register/register.go b/vendor/k8s.io/controller-manager/pkg/features/register/register.go new file mode 100644 index 0000000000..5672dac00c --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/features/register/register.go @@ -0,0 +1,27 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package register + +import ( + "k8s.io/apimachinery/pkg/util/runtime" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/controller-manager/pkg/features" +) + +func init() { + runtime.Must(features.SetupCurrentKubernetesSpecificFeatureGates(utilfeature.DefaultMutableFeatureGate)) +} diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/config/config.go b/vendor/k8s.io/controller-manager/pkg/leadermigration/config/config.go new file mode 100644 index 0000000000..fc8cf17141 --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/leadermigration/config/config.go @@ -0,0 +1,109 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config + +import ( + "fmt" + "os" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + util "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/validation/field" + internal "k8s.io/controller-manager/config" + "k8s.io/controller-manager/config/v1" + "k8s.io/controller-manager/config/v1alpha1" + "k8s.io/controller-manager/config/v1beta1" +) + +// ResourceLockLeases is the resourceLock value for 'leases' API +const ResourceLockLeases = "leases" + +// ResourceLockEndpoints is the resourceLock value for 'endpoints' API +const ResourceLockEndpoints = "endpoints" + +var cfgScheme = runtime.NewScheme() + +func init() { + // internal + util.Must(internal.AddToScheme(cfgScheme)) + + // v1alpha1 + util.Must(v1alpha1.AddToScheme(cfgScheme)) + util.Must(cfgScheme.SetVersionPriority(v1alpha1.SchemeGroupVersion)) + + // v1beta1 + util.Must(v1beta1.AddToScheme(cfgScheme)) + util.Must(cfgScheme.SetVersionPriority(v1beta1.SchemeGroupVersion)) + + // v1 + util.Must(v1.AddToScheme(cfgScheme)) + util.Must(cfgScheme.SetVersionPriority(v1.SchemeGroupVersion)) +} + +// ReadLeaderMigrationConfiguration reads LeaderMigrationConfiguration from a YAML file at the given path. +// The parsed LeaderMigrationConfiguration may be invalid. +// It returns an error if the file did not exist. +func ReadLeaderMigrationConfiguration(configFilePath string) (*internal.LeaderMigrationConfiguration, error) { + data, err := os.ReadFile(configFilePath) + if err != nil { + return nil, fmt.Errorf("unable to read leader migration configuration from %q: %w", configFilePath, err) + } + config, gvk, err := serializer.NewCodecFactory(cfgScheme).UniversalDecoder().Decode(data, nil, nil) + if err != nil { + return nil, err + } + internalConfig, ok := config.(*internal.LeaderMigrationConfiguration) + if !ok { + return nil, fmt.Errorf("unexpected config type: %v", gvk) + } + return internalConfig, nil +} + +// ValidateLeaderMigrationConfiguration validates the LeaderMigrationConfiguration against common errors. +// It checks required names and whether resourceLock is either 'leases' or 'endpoints'. +// It will return nil if it does not find anything wrong. +func ValidateLeaderMigrationConfiguration(config *internal.LeaderMigrationConfiguration) (allErrs field.ErrorList) { + if config.LeaderName == "" { + allErrs = append(allErrs, field.Required(field.NewPath("leaderName"), + "leaderName must be set for LeaderMigrationConfiguration")) + } + if config.ResourceLock != ResourceLockLeases && config.ResourceLock != ResourceLockEndpoints { + allErrs = append(allErrs, field.Invalid(field.NewPath("resourceLock"), config.ResourceLock, + "resource Lock must be one of 'leases' or 'endpoints'")) + } + // validate controllerLeaders + fldPath := field.NewPath("controllerLeaders") + for i, controllerLeader := range config.ControllerLeaders { + path := fldPath.Index(i) + allErrs = append(allErrs, validateControllerLeaderConfiguration(path, &controllerLeader)...) + } + return +} + +func validateControllerLeaderConfiguration(path *field.Path, config *internal.ControllerLeaderConfiguration) (allErrs field.ErrorList) { + if config == nil { + return + } + if config.Component == "" { + allErrs = append(allErrs, field.Required(path.Child("component"), "component must be set")) + } + if config.Name == "" { + allErrs = append(allErrs, field.Required(path.Child("name"), "name must be set")) + } + return +} diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/config/default.go b/vendor/k8s.io/controller-manager/pkg/leadermigration/config/default.go new file mode 100644 index 0000000000..362893b407 --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/leadermigration/config/default.go @@ -0,0 +1,40 @@ +/* +Copyright 2021 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 config + +import internal "k8s.io/controller-manager/config" + +// DefaultLeaderMigrationConfiguration returns the default LeaderMigrationConfiguration +// that is valid for this release of Kubernetes. +func DefaultLeaderMigrationConfiguration() *internal.LeaderMigrationConfiguration { + return &internal.LeaderMigrationConfiguration{ + LeaderName: "cloud-provider-extraction-migration", + ResourceLock: ResourceLockLeases, + ControllerLeaders: []internal.ControllerLeaderConfiguration{ + { + Name: "route", + Component: "*", + }, { + Name: "service", + Component: "*", + }, { + Name: "cloud-node-lifecycle", + Component: "*", + }, + }, + } +} diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/options/options.go b/vendor/k8s.io/controller-manager/pkg/leadermigration/options/options.go new file mode 100644 index 0000000000..abbd75e6f8 --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/leadermigration/options/options.go @@ -0,0 +1,85 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package options + +import ( + "fmt" + + "github.com/spf13/pflag" + "k8s.io/controller-manager/config" + migrationconfig "k8s.io/controller-manager/pkg/leadermigration/config" +) + +// LeaderMigrationOptions is the set of options for Leader Migration, +// which is given to the controller manager through flags +type LeaderMigrationOptions struct { + // Enabled indicates whether leader migration is enabled through the --enabled-leader-migration flag. + Enabled bool + + // ControllerMigrationConfig is the path to the file of LeaderMigrationConfiguration type. + // It can be set with --leader-migration-config flag + // If the path is "" (default vaule), the default vaule will be used. + ControllerMigrationConfig string +} + +// DefaultLeaderMigrationOptions returns a LeaderMigrationOptions with default values. +func DefaultLeaderMigrationOptions() *LeaderMigrationOptions { + return &LeaderMigrationOptions{ + Enabled: false, + ControllerMigrationConfig: "", + } +} + +// AddFlags adds all flags related to leader migration to given flag set. +func (o *LeaderMigrationOptions) AddFlags(fs *pflag.FlagSet) { + if o == nil { + return + } + fs.BoolVar(&o.Enabled, "enable-leader-migration", false, "Whether to enable controller leader migration.") + fs.StringVar(&o.ControllerMigrationConfig, "leader-migration-config", "", + "Path to the config file for controller leader migration, "+ + "or empty to use the value that reflects default configuration of the controller manager. "+ + "The config file should be of type LeaderMigrationConfiguration, group controllermanager.config.k8s.io, version v1alpha1.") +} + +// ApplyTo applies the options of leader migration to generic configuration. +func (o *LeaderMigrationOptions) ApplyTo(cfg *config.GenericControllerManagerConfiguration) error { + if o == nil { + // an nil LeaderMigrationOptions indicates that default options should be used + // in which case leader migration will be disabled + cfg.LeaderMigrationEnabled = false + return nil + } + cfg.LeaderMigrationEnabled = o.Enabled + if !cfg.LeaderMigrationEnabled { + return nil + } + if o.ControllerMigrationConfig == "" { + cfg.LeaderMigration = *migrationconfig.DefaultLeaderMigrationConfiguration() + return nil + } + leaderMigrationConfig, err := migrationconfig.ReadLeaderMigrationConfiguration(o.ControllerMigrationConfig) + if err != nil { + return err + } + errs := migrationconfig.ValidateLeaderMigrationConfiguration(leaderMigrationConfig) + if len(errs) != 0 { + return fmt.Errorf("failed to parse leader migration configuration: %v", errs) + } + cfg.LeaderMigration = *leaderMigrationConfig + return nil +} diff --git a/vendor/k8s.io/klog/v2/contextual.go b/vendor/k8s.io/klog/v2/contextual.go index 2428963c0e..005513f2a7 100644 --- a/vendor/k8s.io/klog/v2/contextual.go +++ b/vendor/k8s.io/klog/v2/contextual.go @@ -70,11 +70,14 @@ func SetLogger(logger logr.Logger) { // routing log entries through klogr into klog and then into the actual Logger // backend. func SetLoggerWithOptions(logger logr.Logger, opts ...LoggerOption) { - logging.logger = &logger logging.loggerOptions = loggerOptions{} for _, opt := range opts { opt(&logging.loggerOptions) } + logging.logger = &logWriter{ + Logger: logger, + writeKlogBuffer: logging.loggerOptions.writeKlogBuffer, + } } // ContextualLogger determines whether the logger passed to @@ -93,6 +96,22 @@ func FlushLogger(flush func()) LoggerOption { } } +// WriteKlogBuffer sets a callback that will be invoked by klog to write output +// produced by non-structured log calls like Infof. +// +// The buffer will contain exactly the same data that klog normally would write +// into its own output stream(s). In particular this includes the header, if +// klog is configured to write one. The callback then can divert that data into +// its own output streams. The buffer may or may not end in a line break. +// +// Without such a callback, klog will call the logger's Info or Error method +// with just the message string (i.e. no header). +func WriteKlogBuffer(write func([]byte)) LoggerOption { + return func(o *loggerOptions) { + o.writeKlogBuffer = write + } +} + // LoggerOption implements the functional parameter paradigm for // SetLoggerWithOptions. type LoggerOption func(o *loggerOptions) @@ -100,6 +119,13 @@ type LoggerOption func(o *loggerOptions) type loggerOptions struct { contextualLogger bool flush func() + writeKlogBuffer func([]byte) +} + +// logWriter combines a logger (always set) with a write callback (optional). +type logWriter struct { + Logger + writeKlogBuffer func([]byte) } // ClearLogger removes a backing Logger implementation if one was set earlier @@ -152,7 +178,7 @@ func Background() Logger { if logging.loggerOptions.contextualLogger { // Is non-nil because logging.loggerOptions.contextualLogger is // only true if a logger was set. - return *logging.logger + return logging.logger.Logger } return klogLogger diff --git a/vendor/k8s.io/klog/v2/internal/buffer/buffer.go b/vendor/k8s.io/klog/v2/internal/buffer/buffer.go index d53b49da39..f325ded5e9 100644 --- a/vendor/k8s.io/klog/v2/internal/buffer/buffer.go +++ b/vendor/k8s.io/klog/v2/internal/buffer/buffer.go @@ -55,6 +55,17 @@ func GetBuffer() *Buffer { // PutBuffer returns a buffer to the free list. func PutBuffer(b *Buffer) { + if b.Len() >= 256 { + // Let big buffers die a natural death, without relying on + // sync.Pool behavior. The documentation implies that items may + // get deallocated while stored there ("If the Pool holds the + // only reference when this [= be removed automatically] + // happens, the item might be deallocated."), but + // https://github.com/golang/go/issues/23199 leans more towards + // having such a size limit. + return + } + buffers.Put(b) } @@ -99,7 +110,8 @@ func (buf *Buffer) someDigits(i, d int) int { return copy(buf.Tmp[i:], buf.Tmp[j:]) } -// FormatHeader formats a log header using the provided file name and line number. +// FormatHeader formats a log header using the provided file name and line number +// and writes it into the buffer. func (buf *Buffer) FormatHeader(s severity.Severity, file string, line int, now time.Time) { if line < 0 { line = 0 // not a real line number, but acceptable to someDigits @@ -135,3 +147,30 @@ func (buf *Buffer) FormatHeader(s severity.Severity, file string, line int, now buf.Tmp[n+2] = ' ' buf.Write(buf.Tmp[:n+3]) } + +// SprintHeader formats a log header and returns a string. This is a simpler +// version of FormatHeader for use in ktesting. +func (buf *Buffer) SprintHeader(s severity.Severity, now time.Time) string { + if s > severity.FatalLog { + s = severity.InfoLog // for safety. + } + + // Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand. + // It's worth about 3X. Fprintf is hard. + _, month, day := now.Date() + hour, minute, second := now.Clock() + // Lmmdd hh:mm:ss.uuuuuu threadid file:line] + buf.Tmp[0] = severity.Char[s] + buf.twoDigits(1, int(month)) + buf.twoDigits(3, day) + buf.Tmp[5] = ' ' + buf.twoDigits(6, hour) + buf.Tmp[8] = ':' + buf.twoDigits(9, minute) + buf.Tmp[11] = ':' + buf.twoDigits(12, second) + buf.Tmp[14] = '.' + buf.nDigits(6, 15, now.Nanosecond()/1000, '0') + buf.Tmp[21] = ']' + return string(buf.Tmp[:22]) +} diff --git a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go index f9558c3d28..1dc81a15fa 100644 --- a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go +++ b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go @@ -95,9 +95,15 @@ func MergeKVs(first, second []interface{}) []interface{} { return merged } +type Formatter struct { + AnyToStringHook AnyToStringFunc +} + +type AnyToStringFunc func(v interface{}) string + // MergeKVsInto is a variant of MergeKVs which directly formats the key/value // pairs into a buffer. -func MergeAndFormatKVs(b *bytes.Buffer, first, second []interface{}) { +func (f Formatter) MergeAndFormatKVs(b *bytes.Buffer, first, second []interface{}) { if len(first) == 0 && len(second) == 0 { // Nothing to do at all. return @@ -107,7 +113,7 @@ func MergeAndFormatKVs(b *bytes.Buffer, first, second []interface{}) { // Nothing to be overridden, second slice is well-formed // and can be used directly. for i := 0; i < len(second); i += 2 { - KVFormat(b, second[i], second[i+1]) + f.KVFormat(b, second[i], second[i+1]) } return } @@ -127,24 +133,28 @@ func MergeAndFormatKVs(b *bytes.Buffer, first, second []interface{}) { if overrides[key] { continue } - KVFormat(b, key, first[i+1]) + f.KVFormat(b, key, first[i+1]) } // Round down. l := len(second) l = l / 2 * 2 for i := 1; i < l; i += 2 { - KVFormat(b, second[i-1], second[i]) + f.KVFormat(b, second[i-1], second[i]) } if len(second)%2 == 1 { - KVFormat(b, second[len(second)-1], missingValue) + f.KVFormat(b, second[len(second)-1], missingValue) } } +func MergeAndFormatKVs(b *bytes.Buffer, first, second []interface{}) { + Formatter{}.MergeAndFormatKVs(b, first, second) +} + const missingValue = "(MISSING)" // KVListFormat serializes all key/value pairs into the provided buffer. // A space gets inserted before the first pair and between each pair. -func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) { +func (f Formatter) KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) { for i := 0; i < len(keysAndValues); i += 2 { var v interface{} k := keysAndValues[i] @@ -153,13 +163,17 @@ func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) { } else { v = missingValue } - KVFormat(b, k, v) + f.KVFormat(b, k, v) } } +func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) { + Formatter{}.KVListFormat(b, keysAndValues...) +} + // KVFormat serializes one key/value pair into the provided buffer. // A space gets inserted before the pair. -func KVFormat(b *bytes.Buffer, k, v interface{}) { +func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) { b.WriteByte(' ') // Keys are assumed to be well-formed according to // https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments @@ -203,7 +217,7 @@ func KVFormat(b *bytes.Buffer, k, v interface{}) { case string: writeStringValue(b, true, value) default: - writeStringValue(b, false, fmt.Sprintf("%+v", value)) + writeStringValue(b, false, f.AnyToString(value)) } case []byte: // In https://github.com/kubernetes/klog/pull/237 it was decided @@ -220,8 +234,20 @@ func KVFormat(b *bytes.Buffer, k, v interface{}) { b.WriteByte('=') b.WriteString(fmt.Sprintf("%+q", v)) default: - writeStringValue(b, false, fmt.Sprintf("%+v", v)) + writeStringValue(b, false, f.AnyToString(v)) + } +} + +func KVFormat(b *bytes.Buffer, k, v interface{}) { + Formatter{}.KVFormat(b, k, v) +} + +// AnyToString is the historic fallback formatter. +func (f Formatter) AnyToString(v interface{}) string { + if f.AnyToStringHook != nil { + return f.AnyToStringHook(v) } + return fmt.Sprintf("%+v", v) } // StringerToString converts a Stringer to a string, diff --git a/vendor/k8s.io/klog/v2/klog.go b/vendor/k8s.io/klog/v2/klog.go index c5d98ad38c..466eeaf265 100644 --- a/vendor/k8s.io/klog/v2/klog.go +++ b/vendor/k8s.io/klog/v2/klog.go @@ -91,8 +91,6 @@ import ( "sync/atomic" "time" - "github.com/go-logr/logr" - "k8s.io/klog/v2/internal/buffer" "k8s.io/klog/v2/internal/clock" "k8s.io/klog/v2/internal/dbg" @@ -453,7 +451,7 @@ type settings struct { // logger is the global Logger chosen by users of klog, nil if // none is available. - logger *Logger + logger *logWriter // loggerOptions contains the options that were supplied for // globalLogger. @@ -525,6 +523,11 @@ func (s settings) deepCopy() settings { } s.vmodule.filter = filter + if s.logger != nil { + logger := *s.logger + s.logger = &logger + } + return s } @@ -668,15 +671,16 @@ func (l *loggingT) formatHeader(s severity.Severity, file string, line int) *buf return buf } -func (l *loggingT) println(s severity.Severity, logger *logr.Logger, filter LogFilter, args ...interface{}) { +func (l *loggingT) println(s severity.Severity, logger *logWriter, filter LogFilter, args ...interface{}) { l.printlnDepth(s, logger, filter, 1, args...) } -func (l *loggingT) printlnDepth(s severity.Severity, logger *logr.Logger, filter LogFilter, depth int, args ...interface{}) { +func (l *loggingT) printlnDepth(s severity.Severity, logger *logWriter, filter LogFilter, depth int, args ...interface{}) { buf, file, line := l.header(s, depth) - // if logger is set, we clear the generated header as we rely on the backing - // logger implementation to print headers - if logger != nil { + // If a logger is set and doesn't support writing a formatted buffer, + // we clear the generated header as we rely on the backing + // logger implementation to print headers. + if logger != nil && logger.writeKlogBuffer == nil { buffer.PutBuffer(buf) buf = buffer.GetBuffer() } @@ -687,15 +691,16 @@ func (l *loggingT) printlnDepth(s severity.Severity, logger *logr.Logger, filter l.output(s, logger, buf, depth, file, line, false) } -func (l *loggingT) print(s severity.Severity, logger *logr.Logger, filter LogFilter, args ...interface{}) { +func (l *loggingT) print(s severity.Severity, logger *logWriter, filter LogFilter, args ...interface{}) { l.printDepth(s, logger, filter, 1, args...) } -func (l *loggingT) printDepth(s severity.Severity, logger *logr.Logger, filter LogFilter, depth int, args ...interface{}) { +func (l *loggingT) printDepth(s severity.Severity, logger *logWriter, filter LogFilter, depth int, args ...interface{}) { buf, file, line := l.header(s, depth) - // if logr is set, we clear the generated header as we rely on the backing - // logr implementation to print headers - if logger != nil { + // If a logger is set and doesn't support writing a formatted buffer, + // we clear the generated header as we rely on the backing + // logger implementation to print headers. + if logger != nil && logger.writeKlogBuffer == nil { buffer.PutBuffer(buf) buf = buffer.GetBuffer() } @@ -709,15 +714,16 @@ func (l *loggingT) printDepth(s severity.Severity, logger *logr.Logger, filter L l.output(s, logger, buf, depth, file, line, false) } -func (l *loggingT) printf(s severity.Severity, logger *logr.Logger, filter LogFilter, format string, args ...interface{}) { +func (l *loggingT) printf(s severity.Severity, logger *logWriter, filter LogFilter, format string, args ...interface{}) { l.printfDepth(s, logger, filter, 1, format, args...) } -func (l *loggingT) printfDepth(s severity.Severity, logger *logr.Logger, filter LogFilter, depth int, format string, args ...interface{}) { +func (l *loggingT) printfDepth(s severity.Severity, logger *logWriter, filter LogFilter, depth int, format string, args ...interface{}) { buf, file, line := l.header(s, depth) - // if logr is set, we clear the generated header as we rely on the backing - // logr implementation to print headers - if logger != nil { + // If a logger is set and doesn't support writing a formatted buffer, + // we clear the generated header as we rely on the backing + // logger implementation to print headers. + if logger != nil && logger.writeKlogBuffer == nil { buffer.PutBuffer(buf) buf = buffer.GetBuffer() } @@ -734,11 +740,12 @@ func (l *loggingT) printfDepth(s severity.Severity, logger *logr.Logger, filter // printWithFileLine behaves like print but uses the provided file and line number. If // alsoLogToStderr is true, the log message always appears on standard error; it // will also appear in the log file unless --logtostderr is set. -func (l *loggingT) printWithFileLine(s severity.Severity, logger *logr.Logger, filter LogFilter, file string, line int, alsoToStderr bool, args ...interface{}) { +func (l *loggingT) printWithFileLine(s severity.Severity, logger *logWriter, filter LogFilter, file string, line int, alsoToStderr bool, args ...interface{}) { buf := l.formatHeader(s, file, line) - // if logr is set, we clear the generated header as we rely on the backing - // logr implementation to print headers - if logger != nil { + // If a logger is set and doesn't support writing a formatted buffer, + // we clear the generated header as we rely on the backing + // logger implementation to print headers. + if logger != nil && logger.writeKlogBuffer == nil { buffer.PutBuffer(buf) buf = buffer.GetBuffer() } @@ -753,7 +760,7 @@ func (l *loggingT) printWithFileLine(s severity.Severity, logger *logr.Logger, f } // if loggr is specified, will call loggr.Error, otherwise output with logging module. -func (l *loggingT) errorS(err error, logger *logr.Logger, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { +func (l *loggingT) errorS(err error, logger *logWriter, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { if filter != nil { msg, keysAndValues = filter.FilterS(msg, keysAndValues) } @@ -765,7 +772,7 @@ func (l *loggingT) errorS(err error, logger *logr.Logger, filter LogFilter, dept } // if loggr is specified, will call loggr.Info, otherwise output with logging module. -func (l *loggingT) infoS(logger *logr.Logger, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { +func (l *loggingT) infoS(logger *logWriter, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { if filter != nil { msg, keysAndValues = filter.FilterS(msg, keysAndValues) } @@ -846,7 +853,7 @@ func LogToStderr(stderr bool) { } // output writes the data to the log files and releases the buffer. -func (l *loggingT) output(s severity.Severity, log *logr.Logger, buf *buffer.Buffer, depth int, file string, line int, alsoToStderr bool) { +func (l *loggingT) output(s severity.Severity, logger *logWriter, buf *buffer.Buffer, depth int, file string, line int, alsoToStderr bool) { var isLocked = true l.mu.Lock() defer func() { @@ -862,13 +869,17 @@ func (l *loggingT) output(s severity.Severity, log *logr.Logger, buf *buffer.Buf } } data := buf.Bytes() - if log != nil { - // TODO: set 'severity' and caller information as structured log info - // keysAndValues := []interface{}{"severity", severityName[s], "file", file, "line", line} - if s == severity.ErrorLog { - logging.logger.WithCallDepth(depth+3).Error(nil, string(data)) + if logger != nil { + if logger.writeKlogBuffer != nil { + logger.writeKlogBuffer(data) } else { - log.WithCallDepth(depth + 3).Info(string(data)) + // TODO: set 'severity' and caller information as structured log info + // keysAndValues := []interface{}{"severity", severityName[s], "file", file, "line", line} + if s == severity.ErrorLog { + logger.WithCallDepth(depth+3).Error(nil, string(data)) + } else { + logger.WithCallDepth(depth + 3).Info(string(data)) + } } } else if l.toStderr { os.Stderr.Write(data) @@ -1277,7 +1288,7 @@ func (l *loggingT) setV(pc uintptr) Level { // See the documentation of V for more information. type Verbose struct { enabled bool - logr *logr.Logger + logger *logWriter } func newVerbose(level Level, b bool) Verbose { @@ -1285,7 +1296,7 @@ func newVerbose(level Level, b bool) Verbose { return Verbose{b, nil} } v := logging.logger.V(int(level)) - return Verbose{b, &v} + return Verbose{b, &logWriter{Logger: v, writeKlogBuffer: logging.loggerOptions.writeKlogBuffer}} } // V reports whether verbosity at the call site is at least the requested level. @@ -1359,7 +1370,7 @@ func (v Verbose) Enabled() bool { // See the documentation of V for usage. func (v Verbose) Info(args ...interface{}) { if v.enabled { - logging.print(severity.InfoLog, v.logr, logging.filter, args...) + logging.print(severity.InfoLog, v.logger, logging.filter, args...) } } @@ -1367,7 +1378,7 @@ func (v Verbose) Info(args ...interface{}) { // See the documentation of V for usage. func (v Verbose) InfoDepth(depth int, args ...interface{}) { if v.enabled { - logging.printDepth(severity.InfoLog, v.logr, logging.filter, depth, args...) + logging.printDepth(severity.InfoLog, v.logger, logging.filter, depth, args...) } } @@ -1375,7 +1386,7 @@ func (v Verbose) InfoDepth(depth int, args ...interface{}) { // See the documentation of V for usage. func (v Verbose) Infoln(args ...interface{}) { if v.enabled { - logging.println(severity.InfoLog, v.logr, logging.filter, args...) + logging.println(severity.InfoLog, v.logger, logging.filter, args...) } } @@ -1383,7 +1394,7 @@ func (v Verbose) Infoln(args ...interface{}) { // See the documentation of V for usage. func (v Verbose) InfolnDepth(depth int, args ...interface{}) { if v.enabled { - logging.printlnDepth(severity.InfoLog, v.logr, logging.filter, depth, args...) + logging.printlnDepth(severity.InfoLog, v.logger, logging.filter, depth, args...) } } @@ -1391,7 +1402,7 @@ func (v Verbose) InfolnDepth(depth int, args ...interface{}) { // See the documentation of V for usage. func (v Verbose) Infof(format string, args ...interface{}) { if v.enabled { - logging.printf(severity.InfoLog, v.logr, logging.filter, format, args...) + logging.printf(severity.InfoLog, v.logger, logging.filter, format, args...) } } @@ -1399,7 +1410,7 @@ func (v Verbose) Infof(format string, args ...interface{}) { // See the documentation of V for usage. func (v Verbose) InfofDepth(depth int, format string, args ...interface{}) { if v.enabled { - logging.printfDepth(severity.InfoLog, v.logr, logging.filter, depth, format, args...) + logging.printfDepth(severity.InfoLog, v.logger, logging.filter, depth, format, args...) } } @@ -1407,7 +1418,7 @@ func (v Verbose) InfofDepth(depth int, format string, args ...interface{}) { // See the documentation of V for usage. func (v Verbose) InfoS(msg string, keysAndValues ...interface{}) { if v.enabled { - logging.infoS(v.logr, logging.filter, 0, msg, keysAndValues...) + logging.infoS(v.logger, logging.filter, 0, msg, keysAndValues...) } } @@ -1421,14 +1432,14 @@ func InfoSDepth(depth int, msg string, keysAndValues ...interface{}) { // See the documentation of V for usage. func (v Verbose) InfoSDepth(depth int, msg string, keysAndValues ...interface{}) { if v.enabled { - logging.infoS(v.logr, logging.filter, depth, msg, keysAndValues...) + logging.infoS(v.logger, logging.filter, depth, msg, keysAndValues...) } } // Deprecated: Use ErrorS instead. func (v Verbose) Error(err error, msg string, args ...interface{}) { if v.enabled { - logging.errorS(err, v.logr, logging.filter, 0, msg, args...) + logging.errorS(err, v.logger, logging.filter, 0, msg, args...) } } @@ -1436,7 +1447,7 @@ func (v Verbose) Error(err error, msg string, args ...interface{}) { // See the documentation of V for usage. func (v Verbose) ErrorS(err error, msg string, keysAndValues ...interface{}) { if v.enabled { - logging.errorS(err, v.logr, logging.filter, 0, msg, keysAndValues...) + logging.errorS(err, v.logger, logging.filter, 0, msg, keysAndValues...) } } diff --git a/vendor/k8s.io/kms/LICENSE b/vendor/k8s.io/kms/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/vendor/k8s.io/kms/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/k8s.io/kms/apis/v1beta1/api.pb.go b/vendor/k8s.io/kms/apis/v1beta1/api.pb.go new file mode 100644 index 0000000000..49c4713fb4 --- /dev/null +++ b/vendor/k8s.io/kms/apis/v1beta1/api.pb.go @@ -0,0 +1,504 @@ +/* +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 protoc-gen-gogo. DO NOT EDIT. +// source: api.proto + +package v1beta1 + +import ( + context "context" + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type VersionRequest struct { + // Version of the KMS plugin API. + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *VersionRequest) Reset() { *m = VersionRequest{} } +func (m *VersionRequest) String() string { return proto.CompactTextString(m) } +func (*VersionRequest) ProtoMessage() {} +func (*VersionRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{0} +} +func (m *VersionRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_VersionRequest.Unmarshal(m, b) +} +func (m *VersionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_VersionRequest.Marshal(b, m, deterministic) +} +func (m *VersionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_VersionRequest.Merge(m, src) +} +func (m *VersionRequest) XXX_Size() int { + return xxx_messageInfo_VersionRequest.Size(m) +} +func (m *VersionRequest) XXX_DiscardUnknown() { + xxx_messageInfo_VersionRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_VersionRequest proto.InternalMessageInfo + +func (m *VersionRequest) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +type VersionResponse struct { + // Version of the KMS plugin API. + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + // Name of the KMS provider. + RuntimeName string `protobuf:"bytes,2,opt,name=runtime_name,json=runtimeName,proto3" json:"runtime_name,omitempty"` + // Version of the KMS provider. The string must be semver-compatible. + RuntimeVersion string `protobuf:"bytes,3,opt,name=runtime_version,json=runtimeVersion,proto3" json:"runtime_version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *VersionResponse) Reset() { *m = VersionResponse{} } +func (m *VersionResponse) String() string { return proto.CompactTextString(m) } +func (*VersionResponse) ProtoMessage() {} +func (*VersionResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{1} +} +func (m *VersionResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_VersionResponse.Unmarshal(m, b) +} +func (m *VersionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_VersionResponse.Marshal(b, m, deterministic) +} +func (m *VersionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_VersionResponse.Merge(m, src) +} +func (m *VersionResponse) XXX_Size() int { + return xxx_messageInfo_VersionResponse.Size(m) +} +func (m *VersionResponse) XXX_DiscardUnknown() { + xxx_messageInfo_VersionResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_VersionResponse proto.InternalMessageInfo + +func (m *VersionResponse) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *VersionResponse) GetRuntimeName() string { + if m != nil { + return m.RuntimeName + } + return "" +} + +func (m *VersionResponse) GetRuntimeVersion() string { + if m != nil { + return m.RuntimeVersion + } + return "" +} + +type DecryptRequest struct { + // Version of the KMS plugin API. + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + // The data to be decrypted. + Cipher []byte `protobuf:"bytes,2,opt,name=cipher,proto3" json:"cipher,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DecryptRequest) Reset() { *m = DecryptRequest{} } +func (m *DecryptRequest) String() string { return proto.CompactTextString(m) } +func (*DecryptRequest) ProtoMessage() {} +func (*DecryptRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{2} +} +func (m *DecryptRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DecryptRequest.Unmarshal(m, b) +} +func (m *DecryptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DecryptRequest.Marshal(b, m, deterministic) +} +func (m *DecryptRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DecryptRequest.Merge(m, src) +} +func (m *DecryptRequest) XXX_Size() int { + return xxx_messageInfo_DecryptRequest.Size(m) +} +func (m *DecryptRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DecryptRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DecryptRequest proto.InternalMessageInfo + +func (m *DecryptRequest) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *DecryptRequest) GetCipher() []byte { + if m != nil { + return m.Cipher + } + return nil +} + +type DecryptResponse struct { + // The decrypted data. + Plain []byte `protobuf:"bytes,1,opt,name=plain,proto3" json:"plain,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DecryptResponse) Reset() { *m = DecryptResponse{} } +func (m *DecryptResponse) String() string { return proto.CompactTextString(m) } +func (*DecryptResponse) ProtoMessage() {} +func (*DecryptResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{3} +} +func (m *DecryptResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DecryptResponse.Unmarshal(m, b) +} +func (m *DecryptResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DecryptResponse.Marshal(b, m, deterministic) +} +func (m *DecryptResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DecryptResponse.Merge(m, src) +} +func (m *DecryptResponse) XXX_Size() int { + return xxx_messageInfo_DecryptResponse.Size(m) +} +func (m *DecryptResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DecryptResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DecryptResponse proto.InternalMessageInfo + +func (m *DecryptResponse) GetPlain() []byte { + if m != nil { + return m.Plain + } + return nil +} + +type EncryptRequest struct { + // Version of the KMS plugin API. + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + // The data to be encrypted. + Plain []byte `protobuf:"bytes,2,opt,name=plain,proto3" json:"plain,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EncryptRequest) Reset() { *m = EncryptRequest{} } +func (m *EncryptRequest) String() string { return proto.CompactTextString(m) } +func (*EncryptRequest) ProtoMessage() {} +func (*EncryptRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{4} +} +func (m *EncryptRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EncryptRequest.Unmarshal(m, b) +} +func (m *EncryptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EncryptRequest.Marshal(b, m, deterministic) +} +func (m *EncryptRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_EncryptRequest.Merge(m, src) +} +func (m *EncryptRequest) XXX_Size() int { + return xxx_messageInfo_EncryptRequest.Size(m) +} +func (m *EncryptRequest) XXX_DiscardUnknown() { + xxx_messageInfo_EncryptRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_EncryptRequest proto.InternalMessageInfo + +func (m *EncryptRequest) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *EncryptRequest) GetPlain() []byte { + if m != nil { + return m.Plain + } + return nil +} + +type EncryptResponse struct { + // The encrypted data. + Cipher []byte `protobuf:"bytes,1,opt,name=cipher,proto3" json:"cipher,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EncryptResponse) Reset() { *m = EncryptResponse{} } +func (m *EncryptResponse) String() string { return proto.CompactTextString(m) } +func (*EncryptResponse) ProtoMessage() {} +func (*EncryptResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{5} +} +func (m *EncryptResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EncryptResponse.Unmarshal(m, b) +} +func (m *EncryptResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EncryptResponse.Marshal(b, m, deterministic) +} +func (m *EncryptResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_EncryptResponse.Merge(m, src) +} +func (m *EncryptResponse) XXX_Size() int { + return xxx_messageInfo_EncryptResponse.Size(m) +} +func (m *EncryptResponse) XXX_DiscardUnknown() { + xxx_messageInfo_EncryptResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_EncryptResponse proto.InternalMessageInfo + +func (m *EncryptResponse) GetCipher() []byte { + if m != nil { + return m.Cipher + } + return nil +} + +func init() { + proto.RegisterType((*VersionRequest)(nil), "v1beta1.VersionRequest") + proto.RegisterType((*VersionResponse)(nil), "v1beta1.VersionResponse") + proto.RegisterType((*DecryptRequest)(nil), "v1beta1.DecryptRequest") + proto.RegisterType((*DecryptResponse)(nil), "v1beta1.DecryptResponse") + proto.RegisterType((*EncryptRequest)(nil), "v1beta1.EncryptRequest") + proto.RegisterType((*EncryptResponse)(nil), "v1beta1.EncryptResponse") +} + +func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } + +var fileDescriptor_00212fb1f9d3bf1c = []byte{ + // 308 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x4f, 0x4b, 0xc3, 0x30, + 0x14, 0x5f, 0x27, 0x6e, 0xec, 0x59, 0x5a, 0x08, 0xc3, 0x55, 0x4f, 0x9a, 0xcb, 0xd4, 0x43, 0xcb, + 0xf4, 0xe2, 0x49, 0x64, 0xe8, 0x49, 0xf4, 0x50, 0xc1, 0x83, 0x17, 0xc9, 0xca, 0x43, 0xc3, 0x6c, + 0x1a, 0x93, 0xac, 0xb2, 0x2f, 0xea, 0xe7, 0x11, 0xdb, 0xb4, 0xa6, 0x13, 0xd1, 0xe3, 0x7b, 0xf9, + 0xfd, 0x79, 0xbf, 0xf7, 0x02, 0x23, 0x26, 0x79, 0x2c, 0x55, 0x61, 0x0a, 0x32, 0x2c, 0x67, 0x0b, + 0x34, 0x6c, 0x46, 0x4f, 0x20, 0x78, 0x40, 0xa5, 0x79, 0x21, 0x52, 0x7c, 0x5b, 0xa1, 0x36, 0x24, + 0x82, 0x61, 0x59, 0x77, 0x22, 0xef, 0xc0, 0x3b, 0x1a, 0xa5, 0x4d, 0x49, 0xdf, 0x21, 0x6c, 0xb1, + 0x5a, 0x16, 0x42, 0xe3, 0xef, 0x60, 0x72, 0x08, 0xbe, 0x5a, 0x09, 0xc3, 0x73, 0x7c, 0x12, 0x2c, + 0xc7, 0xa8, 0x5f, 0x3d, 0xef, 0xd8, 0xde, 0x1d, 0xcb, 0x91, 0x4c, 0x21, 0x6c, 0x20, 0x8d, 0xc8, + 0x56, 0x85, 0x0a, 0x6c, 0xdb, 0xba, 0xd1, 0x39, 0x04, 0x57, 0x98, 0xa9, 0xb5, 0x34, 0x7f, 0x0e, + 0x49, 0x76, 0x61, 0x90, 0x71, 0xf9, 0x82, 0xaa, 0x72, 0xf4, 0x53, 0x5b, 0xd1, 0x29, 0x84, 0xad, + 0x86, 0x1d, 0x7e, 0x0c, 0xdb, 0xf2, 0x95, 0xf1, 0x5a, 0xc2, 0x4f, 0xeb, 0x82, 0x5e, 0x42, 0x70, + 0x2d, 0xfe, 0x69, 0xd6, 0x2a, 0xf4, 0x5d, 0x85, 0x63, 0x08, 0x5b, 0x05, 0x6b, 0xf5, 0x3d, 0x95, + 0xe7, 0x4e, 0x75, 0xfa, 0xe1, 0xc1, 0xf8, 0x06, 0xd7, 0xb7, 0x4c, 0xb0, 0x67, 0xcc, 0x51, 0x98, + 0x7b, 0x54, 0x25, 0xcf, 0x90, 0x5c, 0xc0, 0xd0, 0xa6, 0x27, 0x93, 0xd8, 0x1e, 0x2b, 0xee, 0x5e, + 0x6a, 0x3f, 0xfa, 0xf9, 0x50, 0xdb, 0xd1, 0xde, 0x17, 0xdf, 0xc6, 0x75, 0xf8, 0xdd, 0x25, 0x3a, + 0xfc, 0x8d, 0xcd, 0xd4, 0x7c, 0x9b, 0xc1, 0xe1, 0x77, 0xf7, 0xe2, 0xf0, 0x37, 0xe2, 0xd2, 0xde, + 0x7c, 0xef, 0x71, 0xb2, 0x3c, 0xd7, 0x31, 0x2f, 0x92, 0x65, 0xae, 0x13, 0x26, 0xb9, 0x4e, 0x2c, + 0x78, 0x31, 0xa8, 0xbe, 0xe0, 0xd9, 0x67, 0x00, 0x00, 0x00, 0xff, 0xff, 0x13, 0xcb, 0x8d, 0x9b, + 0x8f, 0x02, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// KeyManagementServiceClient is the client API for KeyManagementService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type KeyManagementServiceClient interface { + // Version returns the runtime name and runtime version of the KMS provider. + Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionResponse, error) + // Execute decryption operation in KMS provider. + Decrypt(ctx context.Context, in *DecryptRequest, opts ...grpc.CallOption) (*DecryptResponse, error) + // Execute encryption operation in KMS provider. + Encrypt(ctx context.Context, in *EncryptRequest, opts ...grpc.CallOption) (*EncryptResponse, error) +} + +type keyManagementServiceClient struct { + cc *grpc.ClientConn +} + +func NewKeyManagementServiceClient(cc *grpc.ClientConn) KeyManagementServiceClient { + return &keyManagementServiceClient{cc} +} + +func (c *keyManagementServiceClient) Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionResponse, error) { + out := new(VersionResponse) + err := c.cc.Invoke(ctx, "/v1beta1.KeyManagementService/Version", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keyManagementServiceClient) Decrypt(ctx context.Context, in *DecryptRequest, opts ...grpc.CallOption) (*DecryptResponse, error) { + out := new(DecryptResponse) + err := c.cc.Invoke(ctx, "/v1beta1.KeyManagementService/Decrypt", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keyManagementServiceClient) Encrypt(ctx context.Context, in *EncryptRequest, opts ...grpc.CallOption) (*EncryptResponse, error) { + out := new(EncryptResponse) + err := c.cc.Invoke(ctx, "/v1beta1.KeyManagementService/Encrypt", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// KeyManagementServiceServer is the server API for KeyManagementService service. +type KeyManagementServiceServer interface { + // Version returns the runtime name and runtime version of the KMS provider. + Version(context.Context, *VersionRequest) (*VersionResponse, error) + // Execute decryption operation in KMS provider. + Decrypt(context.Context, *DecryptRequest) (*DecryptResponse, error) + // Execute encryption operation in KMS provider. + Encrypt(context.Context, *EncryptRequest) (*EncryptResponse, error) +} + +// UnimplementedKeyManagementServiceServer can be embedded to have forward compatible implementations. +type UnimplementedKeyManagementServiceServer struct { +} + +func (*UnimplementedKeyManagementServiceServer) Version(ctx context.Context, req *VersionRequest) (*VersionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Version not implemented") +} +func (*UnimplementedKeyManagementServiceServer) Decrypt(ctx context.Context, req *DecryptRequest) (*DecryptResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Decrypt not implemented") +} +func (*UnimplementedKeyManagementServiceServer) Encrypt(ctx context.Context, req *EncryptRequest) (*EncryptResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Encrypt not implemented") +} + +func RegisterKeyManagementServiceServer(s *grpc.Server, srv KeyManagementServiceServer) { + s.RegisterService(&_KeyManagementService_serviceDesc, srv) +} + +func _KeyManagementService_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VersionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeyManagementServiceServer).Version(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v1beta1.KeyManagementService/Version", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeyManagementServiceServer).Version(ctx, req.(*VersionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _KeyManagementService_Decrypt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DecryptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeyManagementServiceServer).Decrypt(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v1beta1.KeyManagementService/Decrypt", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeyManagementServiceServer).Decrypt(ctx, req.(*DecryptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _KeyManagementService_Encrypt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EncryptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeyManagementServiceServer).Encrypt(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v1beta1.KeyManagementService/Encrypt", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeyManagementServiceServer).Encrypt(ctx, req.(*EncryptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _KeyManagementService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "v1beta1.KeyManagementService", + HandlerType: (*KeyManagementServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Version", + Handler: _KeyManagementService_Version_Handler, + }, + { + MethodName: "Decrypt", + Handler: _KeyManagementService_Decrypt_Handler, + }, + { + MethodName: "Encrypt", + Handler: _KeyManagementService_Encrypt_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api.proto", +} diff --git a/vendor/k8s.io/kms/apis/v1beta1/api.proto b/vendor/k8s.io/kms/apis/v1beta1/api.proto new file mode 100644 index 0000000000..22450edcd8 --- /dev/null +++ b/vendor/k8s.io/kms/apis/v1beta1/api.proto @@ -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. +*/ + +// To regenerate api.pb.go run `hack/update-codegen.sh protobindings` +syntax = "proto3"; + +package v1beta1; +option go_package = "k8s.io/kms/apis/v1beta1"; + +// This service defines the public APIs for remote KMS provider. +service KeyManagementService { + // Version returns the runtime name and runtime version of the KMS provider. + rpc Version(VersionRequest) returns (VersionResponse) {} + + // Execute decryption operation in KMS provider. + rpc Decrypt(DecryptRequest) returns (DecryptResponse) {} + // Execute encryption operation in KMS provider. + rpc Encrypt(EncryptRequest) returns (EncryptResponse) {} +} + +message VersionRequest { + // Version of the KMS plugin API. + string version = 1; +} + +message VersionResponse { + // Version of the KMS plugin API. + string version = 1; + // Name of the KMS provider. + string runtime_name = 2; + // Version of the KMS provider. The string must be semver-compatible. + string runtime_version = 3; +} + +message DecryptRequest { + // Version of the KMS plugin API. + string version = 1; + // The data to be decrypted. + bytes cipher = 2; +} + +message DecryptResponse { + // The decrypted data. + bytes plain = 1; +} + +message EncryptRequest { + // Version of the KMS plugin API. + string version = 1; + // The data to be encrypted. + bytes plain = 2; +} + +message EncryptResponse { + // The encrypted data. + bytes cipher = 1; +} + diff --git a/vendor/k8s.io/kms/apis/v1beta1/v1beta1.go b/vendor/k8s.io/kms/apis/v1beta1/v1beta1.go new file mode 100644 index 0000000000..842d0a2fdc --- /dev/null +++ b/vendor/k8s.io/kms/apis/v1beta1/v1beta1.go @@ -0,0 +1,23 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1beta1 contains definition of kms-plugin's gRPC service. +package v1beta1 + +// IsVersionCheckMethod determines whether the supplied method is a version check against kms-plugin. +func IsVersionCheckMethod(method string) bool { + return method == "/v1beta1.KeyManagementService/Version" +} diff --git a/vendor/k8s.io/kms/apis/v2/api.pb.go b/vendor/k8s.io/kms/apis/v2/api.pb.go new file mode 100644 index 0000000000..cb746a64c9 --- /dev/null +++ b/vendor/k8s.io/kms/apis/v2/api.pb.go @@ -0,0 +1,543 @@ +/* +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 protoc-gen-gogo. DO NOT EDIT. +// source: api.proto + +package v2 + +import ( + context "context" + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type StatusRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StatusRequest) Reset() { *m = StatusRequest{} } +func (m *StatusRequest) String() string { return proto.CompactTextString(m) } +func (*StatusRequest) ProtoMessage() {} +func (*StatusRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{0} +} +func (m *StatusRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StatusRequest.Unmarshal(m, b) +} +func (m *StatusRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StatusRequest.Marshal(b, m, deterministic) +} +func (m *StatusRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StatusRequest.Merge(m, src) +} +func (m *StatusRequest) XXX_Size() int { + return xxx_messageInfo_StatusRequest.Size(m) +} +func (m *StatusRequest) XXX_DiscardUnknown() { + xxx_messageInfo_StatusRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_StatusRequest proto.InternalMessageInfo + +type StatusResponse struct { + // Version of the KMS plugin API. Must match the configured .resources[].providers[].kms.apiVersion + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + // Any value other than "ok" is failing healthz. On failure, the associated API server healthz endpoint will contain this value as part of the error message. + Healthz string `protobuf:"bytes,2,opt,name=healthz,proto3" json:"healthz,omitempty"` + // the current write key, used to determine staleness of data updated via value.Transformer.TransformFromStorage. + KeyId string `protobuf:"bytes,3,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StatusResponse) Reset() { *m = StatusResponse{} } +func (m *StatusResponse) String() string { return proto.CompactTextString(m) } +func (*StatusResponse) ProtoMessage() {} +func (*StatusResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{1} +} +func (m *StatusResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StatusResponse.Unmarshal(m, b) +} +func (m *StatusResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StatusResponse.Marshal(b, m, deterministic) +} +func (m *StatusResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StatusResponse.Merge(m, src) +} +func (m *StatusResponse) XXX_Size() int { + return xxx_messageInfo_StatusResponse.Size(m) +} +func (m *StatusResponse) XXX_DiscardUnknown() { + xxx_messageInfo_StatusResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_StatusResponse proto.InternalMessageInfo + +func (m *StatusResponse) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *StatusResponse) GetHealthz() string { + if m != nil { + return m.Healthz + } + return "" +} + +func (m *StatusResponse) GetKeyId() string { + if m != nil { + return m.KeyId + } + return "" +} + +type DecryptRequest struct { + // The data to be decrypted. + Ciphertext []byte `protobuf:"bytes,1,opt,name=ciphertext,proto3" json:"ciphertext,omitempty"` + // UID is a unique identifier for the request. + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + // The keyID that was provided to the apiserver during encryption. + // This represents the KMS KEK that was used to encrypt the data. + KeyId string `protobuf:"bytes,3,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` + // Additional metadata that was sent by the KMS plugin during encryption. + Annotations map[string][]byte `protobuf:"bytes,4,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DecryptRequest) Reset() { *m = DecryptRequest{} } +func (m *DecryptRequest) String() string { return proto.CompactTextString(m) } +func (*DecryptRequest) ProtoMessage() {} +func (*DecryptRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{2} +} +func (m *DecryptRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DecryptRequest.Unmarshal(m, b) +} +func (m *DecryptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DecryptRequest.Marshal(b, m, deterministic) +} +func (m *DecryptRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DecryptRequest.Merge(m, src) +} +func (m *DecryptRequest) XXX_Size() int { + return xxx_messageInfo_DecryptRequest.Size(m) +} +func (m *DecryptRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DecryptRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DecryptRequest proto.InternalMessageInfo + +func (m *DecryptRequest) GetCiphertext() []byte { + if m != nil { + return m.Ciphertext + } + return nil +} + +func (m *DecryptRequest) GetUid() string { + if m != nil { + return m.Uid + } + return "" +} + +func (m *DecryptRequest) GetKeyId() string { + if m != nil { + return m.KeyId + } + return "" +} + +func (m *DecryptRequest) GetAnnotations() map[string][]byte { + if m != nil { + return m.Annotations + } + return nil +} + +type DecryptResponse struct { + // The decrypted data. + Plaintext []byte `protobuf:"bytes,1,opt,name=plaintext,proto3" json:"plaintext,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DecryptResponse) Reset() { *m = DecryptResponse{} } +func (m *DecryptResponse) String() string { return proto.CompactTextString(m) } +func (*DecryptResponse) ProtoMessage() {} +func (*DecryptResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{3} +} +func (m *DecryptResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DecryptResponse.Unmarshal(m, b) +} +func (m *DecryptResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DecryptResponse.Marshal(b, m, deterministic) +} +func (m *DecryptResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DecryptResponse.Merge(m, src) +} +func (m *DecryptResponse) XXX_Size() int { + return xxx_messageInfo_DecryptResponse.Size(m) +} +func (m *DecryptResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DecryptResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DecryptResponse proto.InternalMessageInfo + +func (m *DecryptResponse) GetPlaintext() []byte { + if m != nil { + return m.Plaintext + } + return nil +} + +type EncryptRequest struct { + // The data to be encrypted. + Plaintext []byte `protobuf:"bytes,1,opt,name=plaintext,proto3" json:"plaintext,omitempty"` + // UID is a unique identifier for the request. + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EncryptRequest) Reset() { *m = EncryptRequest{} } +func (m *EncryptRequest) String() string { return proto.CompactTextString(m) } +func (*EncryptRequest) ProtoMessage() {} +func (*EncryptRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{4} +} +func (m *EncryptRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EncryptRequest.Unmarshal(m, b) +} +func (m *EncryptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EncryptRequest.Marshal(b, m, deterministic) +} +func (m *EncryptRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_EncryptRequest.Merge(m, src) +} +func (m *EncryptRequest) XXX_Size() int { + return xxx_messageInfo_EncryptRequest.Size(m) +} +func (m *EncryptRequest) XXX_DiscardUnknown() { + xxx_messageInfo_EncryptRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_EncryptRequest proto.InternalMessageInfo + +func (m *EncryptRequest) GetPlaintext() []byte { + if m != nil { + return m.Plaintext + } + return nil +} + +func (m *EncryptRequest) GetUid() string { + if m != nil { + return m.Uid + } + return "" +} + +type EncryptResponse struct { + // The encrypted data. + Ciphertext []byte `protobuf:"bytes,1,opt,name=ciphertext,proto3" json:"ciphertext,omitempty"` + // The KMS key ID used to encrypt the data. This must always refer to the KMS KEK and not any local KEKs that may be in use. + // This can be used to inform staleness of data updated via value.Transformer.TransformFromStorage. + KeyId string `protobuf:"bytes,2,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` + // Additional metadata to be stored with the encrypted data. + // This metadata can contain the encrypted local KEK that was used to encrypt the DEK. + // This data is stored in plaintext in etcd. KMS plugin implementations are responsible for pre-encrypting any sensitive data. + Annotations map[string][]byte `protobuf:"bytes,3,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EncryptResponse) Reset() { *m = EncryptResponse{} } +func (m *EncryptResponse) String() string { return proto.CompactTextString(m) } +func (*EncryptResponse) ProtoMessage() {} +func (*EncryptResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{5} +} +func (m *EncryptResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EncryptResponse.Unmarshal(m, b) +} +func (m *EncryptResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EncryptResponse.Marshal(b, m, deterministic) +} +func (m *EncryptResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_EncryptResponse.Merge(m, src) +} +func (m *EncryptResponse) XXX_Size() int { + return xxx_messageInfo_EncryptResponse.Size(m) +} +func (m *EncryptResponse) XXX_DiscardUnknown() { + xxx_messageInfo_EncryptResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_EncryptResponse proto.InternalMessageInfo + +func (m *EncryptResponse) GetCiphertext() []byte { + if m != nil { + return m.Ciphertext + } + return nil +} + +func (m *EncryptResponse) GetKeyId() string { + if m != nil { + return m.KeyId + } + return "" +} + +func (m *EncryptResponse) GetAnnotations() map[string][]byte { + if m != nil { + return m.Annotations + } + return nil +} + +func init() { + proto.RegisterType((*StatusRequest)(nil), "v2.StatusRequest") + proto.RegisterType((*StatusResponse)(nil), "v2.StatusResponse") + proto.RegisterType((*DecryptRequest)(nil), "v2.DecryptRequest") + proto.RegisterMapType((map[string][]byte)(nil), "v2.DecryptRequest.AnnotationsEntry") + proto.RegisterType((*DecryptResponse)(nil), "v2.DecryptResponse") + proto.RegisterType((*EncryptRequest)(nil), "v2.EncryptRequest") + proto.RegisterType((*EncryptResponse)(nil), "v2.EncryptResponse") + proto.RegisterMapType((map[string][]byte)(nil), "v2.EncryptResponse.AnnotationsEntry") +} + +func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } + +var fileDescriptor_00212fb1f9d3bf1c = []byte{ + // 403 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0xcd, 0x6e, 0xda, 0x40, + 0x10, 0xc7, 0xb1, 0x5d, 0x40, 0x0c, 0x14, 0xe8, 0x96, 0x4a, 0x16, 0xaa, 0x2a, 0xb4, 0xed, 0x81, + 0x93, 0xad, 0xba, 0x3d, 0xa0, 0x1e, 0xaa, 0xb6, 0x2a, 0x95, 0xaa, 0xaa, 0x17, 0x73, 0x6b, 0x0f, + 0xd1, 0x06, 0x46, 0x61, 0x65, 0x58, 0x3b, 0xde, 0xb5, 0x15, 0xe7, 0xbd, 0xf2, 0x1e, 0x79, 0x84, + 0x3c, 0x4a, 0x64, 0x7b, 0x01, 0x1b, 0x94, 0xe4, 0x94, 0x9b, 0xe7, 0xf3, 0x3f, 0xf3, 0xdb, 0x31, + 0x74, 0x58, 0xc4, 0x9d, 0x28, 0x0e, 0x55, 0x48, 0xcc, 0xd4, 0xa3, 0x03, 0x78, 0xb9, 0x50, 0x4c, + 0x25, 0xd2, 0xc7, 0xcb, 0x04, 0xa5, 0xa2, 0xff, 0xa1, 0xbf, 0x73, 0xc8, 0x28, 0x14, 0x12, 0x89, + 0x0d, 0xed, 0x14, 0x63, 0xc9, 0x43, 0x61, 0x1b, 0x13, 0x63, 0xda, 0xf1, 0x77, 0x66, 0x1e, 0x59, + 0x23, 0xdb, 0xa8, 0xf5, 0xb5, 0x6d, 0x96, 0x11, 0x6d, 0x92, 0x37, 0xd0, 0x0a, 0x30, 0x3b, 0xe3, + 0x2b, 0xdb, 0x2a, 0x02, 0xcd, 0x00, 0xb3, 0xdf, 0x2b, 0x7a, 0x67, 0x40, 0xff, 0x27, 0x2e, 0xe3, + 0x2c, 0x52, 0x5a, 0x8f, 0xbc, 0x03, 0x58, 0xf2, 0x68, 0x8d, 0xb1, 0xc2, 0x2b, 0x55, 0x08, 0xf4, + 0xfc, 0x8a, 0x87, 0x0c, 0xc1, 0x4a, 0xf8, 0x4a, 0xf7, 0xcf, 0x3f, 0x1f, 0xe8, 0x4d, 0xe6, 0xd0, + 0x65, 0x42, 0x84, 0x8a, 0x29, 0x1e, 0x0a, 0x69, 0xbf, 0x98, 0x58, 0xd3, 0xae, 0xf7, 0xde, 0x49, + 0x3d, 0xa7, 0xae, 0xe8, 0x7c, 0x3f, 0x64, 0xcd, 0x85, 0x8a, 0x33, 0xbf, 0x5a, 0x37, 0xfe, 0x0a, + 0xc3, 0xe3, 0x84, 0x7c, 0x86, 0x00, 0x33, 0xbd, 0x7d, 0xfe, 0x49, 0x46, 0xd0, 0x4c, 0xd9, 0x26, + 0xc1, 0x62, 0xae, 0x9e, 0x5f, 0x1a, 0x5f, 0xcc, 0x99, 0x41, 0x5d, 0x18, 0xec, 0xf5, 0x34, 0xc0, + 0xb7, 0xd0, 0x89, 0x36, 0x8c, 0x8b, 0xca, 0x86, 0x07, 0x07, 0xfd, 0x06, 0xfd, 0xb9, 0xa8, 0x21, + 0x79, 0x34, 0xff, 0x14, 0x08, 0xbd, 0x35, 0x60, 0xb0, 0x6f, 0xa1, 0x35, 0x9f, 0xc2, 0x7a, 0x80, + 0x68, 0x56, 0x21, 0xfe, 0xaa, 0x43, 0xb4, 0x0a, 0x88, 0x1f, 0x72, 0x88, 0x47, 0x02, 0xcf, 0x4b, + 0xd1, 0xbb, 0x31, 0x60, 0xf4, 0x07, 0xb3, 0xbf, 0x4c, 0xb0, 0x0b, 0xdc, 0xa2, 0x50, 0x0b, 0x8c, + 0x53, 0xbe, 0x44, 0xf2, 0x11, 0x5a, 0xe5, 0x79, 0x92, 0x57, 0xf9, 0x54, 0xb5, 0xdb, 0x1d, 0x93, + 0xaa, 0xab, 0x9c, 0x93, 0x36, 0xc8, 0x67, 0x68, 0xeb, 0x17, 0x21, 0xe4, 0xf4, 0x1c, 0xc6, 0xaf, + 0x6b, 0xbe, 0x6a, 0x95, 0x5e, 0xb9, 0xac, 0xaa, 0xbf, 0x51, 0x59, 0x75, 0xc4, 0x84, 0x36, 0x7e, + 0x8c, 0xfe, 0x91, 0x60, 0x26, 0x1d, 0x1e, 0xba, 0xc1, 0x56, 0xba, 0x2c, 0xe2, 0xd2, 0x4d, 0xbd, + 0xf3, 0x56, 0xf1, 0xbf, 0x7d, 0xba, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x5f, 0xf8, 0x49, 0x17, 0x7c, + 0x03, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// KeyManagementServiceClient is the client API for KeyManagementService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type KeyManagementServiceClient interface { + // this API is meant to be polled + Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) + // Execute decryption operation in KMS provider. + Decrypt(ctx context.Context, in *DecryptRequest, opts ...grpc.CallOption) (*DecryptResponse, error) + // Execute encryption operation in KMS provider. + Encrypt(ctx context.Context, in *EncryptRequest, opts ...grpc.CallOption) (*EncryptResponse, error) +} + +type keyManagementServiceClient struct { + cc *grpc.ClientConn +} + +func NewKeyManagementServiceClient(cc *grpc.ClientConn) KeyManagementServiceClient { + return &keyManagementServiceClient{cc} +} + +func (c *keyManagementServiceClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) { + out := new(StatusResponse) + err := c.cc.Invoke(ctx, "/v2.KeyManagementService/Status", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keyManagementServiceClient) Decrypt(ctx context.Context, in *DecryptRequest, opts ...grpc.CallOption) (*DecryptResponse, error) { + out := new(DecryptResponse) + err := c.cc.Invoke(ctx, "/v2.KeyManagementService/Decrypt", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keyManagementServiceClient) Encrypt(ctx context.Context, in *EncryptRequest, opts ...grpc.CallOption) (*EncryptResponse, error) { + out := new(EncryptResponse) + err := c.cc.Invoke(ctx, "/v2.KeyManagementService/Encrypt", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// KeyManagementServiceServer is the server API for KeyManagementService service. +type KeyManagementServiceServer interface { + // this API is meant to be polled + Status(context.Context, *StatusRequest) (*StatusResponse, error) + // Execute decryption operation in KMS provider. + Decrypt(context.Context, *DecryptRequest) (*DecryptResponse, error) + // Execute encryption operation in KMS provider. + Encrypt(context.Context, *EncryptRequest) (*EncryptResponse, error) +} + +// UnimplementedKeyManagementServiceServer can be embedded to have forward compatible implementations. +type UnimplementedKeyManagementServiceServer struct { +} + +func (*UnimplementedKeyManagementServiceServer) Status(ctx context.Context, req *StatusRequest) (*StatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Status not implemented") +} +func (*UnimplementedKeyManagementServiceServer) Decrypt(ctx context.Context, req *DecryptRequest) (*DecryptResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Decrypt not implemented") +} +func (*UnimplementedKeyManagementServiceServer) Encrypt(ctx context.Context, req *EncryptRequest) (*EncryptResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Encrypt not implemented") +} + +func RegisterKeyManagementServiceServer(s *grpc.Server, srv KeyManagementServiceServer) { + s.RegisterService(&_KeyManagementService_serviceDesc, srv) +} + +func _KeyManagementService_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeyManagementServiceServer).Status(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v2.KeyManagementService/Status", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeyManagementServiceServer).Status(ctx, req.(*StatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _KeyManagementService_Decrypt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DecryptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeyManagementServiceServer).Decrypt(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v2.KeyManagementService/Decrypt", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeyManagementServiceServer).Decrypt(ctx, req.(*DecryptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _KeyManagementService_Encrypt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EncryptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeyManagementServiceServer).Encrypt(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v2.KeyManagementService/Encrypt", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeyManagementServiceServer).Encrypt(ctx, req.(*EncryptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _KeyManagementService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "v2.KeyManagementService", + HandlerType: (*KeyManagementServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Status", + Handler: _KeyManagementService_Status_Handler, + }, + { + MethodName: "Decrypt", + Handler: _KeyManagementService_Decrypt_Handler, + }, + { + MethodName: "Encrypt", + Handler: _KeyManagementService_Encrypt_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api.proto", +} diff --git a/vendor/k8s.io/kms/apis/v2/api.proto b/vendor/k8s.io/kms/apis/v2/api.proto new file mode 100644 index 0000000000..09b52126f2 --- /dev/null +++ b/vendor/k8s.io/kms/apis/v2/api.proto @@ -0,0 +1,79 @@ +/* +Copyright 2022 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. +*/ + +// To regenerate api.pb.go run `hack/update-codegen.sh protobindings` +syntax = "proto3"; + +package v2; +option go_package = "k8s.io/kms/apis/v2"; + +// This service defines the public APIs for remote KMS provider. +service KeyManagementService { + // this API is meant to be polled + rpc Status(StatusRequest) returns (StatusResponse) {} + + // Execute decryption operation in KMS provider. + rpc Decrypt(DecryptRequest) returns (DecryptResponse) {} + // Execute encryption operation in KMS provider. + rpc Encrypt(EncryptRequest) returns (EncryptResponse) {} +} + +message StatusRequest {} + +message StatusResponse { + // Version of the KMS plugin API. Must match the configured .resources[].providers[].kms.apiVersion + string version = 1; + // Any value other than "ok" is failing healthz. On failure, the associated API server healthz endpoint will contain this value as part of the error message. + string healthz = 2; + // the current write key, used to determine staleness of data updated via value.Transformer.TransformFromStorage. + string key_id = 3; +} + +message DecryptRequest { + // The data to be decrypted. + bytes ciphertext = 1; + // UID is a unique identifier for the request. + string uid = 2; + // The keyID that was provided to the apiserver during encryption. + // This represents the KMS KEK that was used to encrypt the data. + string key_id = 3; + // Additional metadata that was sent by the KMS plugin during encryption. + map annotations = 4; +} + +message DecryptResponse { + // The decrypted data. + bytes plaintext = 1; +} + +message EncryptRequest { + // The data to be encrypted. + bytes plaintext = 1; + // UID is a unique identifier for the request. + string uid = 2; +} + +message EncryptResponse { + // The encrypted data. + bytes ciphertext = 1; + // The KMS key ID used to encrypt the data. This must always refer to the KMS KEK and not any local KEKs that may be in use. + // This can be used to inform staleness of data updated via value.Transformer.TransformFromStorage. + string key_id = 2; + // Additional metadata to be stored with the encrypted data. + // This metadata can contain the encrypted local KEK that was used to encrypt the DEK. + // This data is stored in plaintext in etcd. KMS plugin implementations are responsible for pre-encrypting any sensitive data. + map annotations = 3; +} diff --git a/vendor/github.com/jmespath/go-jmespath/LICENSE b/vendor/k8s.io/kms/apis/v2/v2.go similarity index 81% rename from vendor/github.com/jmespath/go-jmespath/LICENSE rename to vendor/k8s.io/kms/apis/v2/v2.go index b03310a91f..99c4b57cc0 100644 --- a/vendor/github.com/jmespath/go-jmespath/LICENSE +++ b/vendor/k8s.io/kms/apis/v2/v2.go @@ -1,4 +1,5 @@ -Copyright 2015 James Saryerwinnie +/* +Copyright 2022 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. @@ -11,3 +12,7 @@ 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 v2 contains definition of kms-plugin's gRPC service. +package v2 diff --git a/vendor/k8s.io/kms/pkg/service/grpc_service.go b/vendor/k8s.io/kms/pkg/service/grpc_service.go new file mode 100644 index 0000000000..fc463e5c4a --- /dev/null +++ b/vendor/k8s.io/kms/pkg/service/grpc_service.go @@ -0,0 +1,141 @@ +/* +Copyright 2023 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 service + +import ( + "context" + "net" + "time" + + "google.golang.org/grpc" + + "k8s.io/klog/v2" + kmsapi "k8s.io/kms/apis/v2" +) + +// GRPCService is a grpc server that runs the kms v2 alpha1 API. +type GRPCService struct { + addr string + timeout time.Duration + server *grpc.Server + + kmsService Service +} + +var _ kmsapi.KeyManagementServiceServer = (*GRPCService)(nil) + +// NewGRPCService creates an instance of GRPCService. +func NewGRPCService( + address string, + timeout time.Duration, + + kmsService Service, +) *GRPCService { + klog.V(4).InfoS("KMS plugin configured", "address", address, "timeout", timeout) + + return &GRPCService{ + addr: address, + timeout: timeout, + kmsService: kmsService, + } +} + +// ListenAndServe accepts incoming connections on a Unix socket. It is a blocking method. +// Returns non-nil error unless Close or Shutdown is called. +func (s *GRPCService) ListenAndServe() error { + ln, err := net.Listen("unix", s.addr) + if err != nil { + return err + } + defer ln.Close() + + gs := grpc.NewServer( + grpc.ConnectionTimeout(s.timeout), + ) + s.server = gs + + kmsapi.RegisterKeyManagementServiceServer(gs, s) + + klog.V(4).InfoS("kms plugin serving", "address", s.addr) + return gs.Serve(ln) +} + +// Shutdown performs a graceful shutdown. Doesn't accept new connections and +// blocks until all pending RPCs are finished. +func (s *GRPCService) Shutdown() { + klog.V(4).InfoS("kms plugin shutdown", "address", s.addr) + if s.server != nil { + s.server.GracefulStop() + } +} + +// Close stops the server by closing all connections immediately and cancels +// all active RPCs. +func (s *GRPCService) Close() { + klog.V(4).InfoS("kms plugin close", "address", s.addr) + if s.server != nil { + s.server.Stop() + } +} + +// Status sends a status request to specified kms service. +func (s *GRPCService) Status(ctx context.Context, _ *kmsapi.StatusRequest) (*kmsapi.StatusResponse, error) { + res, err := s.kmsService.Status(ctx) + if err != nil { + return nil, err + } + + return &kmsapi.StatusResponse{ + Version: res.Version, + Healthz: res.Healthz, + KeyId: res.KeyID, + }, nil +} + +// Decrypt sends a decryption request to specified kms service. +func (s *GRPCService) Decrypt(ctx context.Context, req *kmsapi.DecryptRequest) (*kmsapi.DecryptResponse, error) { + klog.V(4).InfoS("decrypt request received", "id", req.Uid) + + plaintext, err := s.kmsService.Decrypt(ctx, req.Uid, &DecryptRequest{ + Ciphertext: req.Ciphertext, + KeyID: req.KeyId, + Annotations: req.Annotations, + }) + if err != nil { + return nil, err + } + + return &kmsapi.DecryptResponse{ + Plaintext: plaintext, + }, nil +} + +// Encrypt sends an encryption request to specified kms service. +func (s *GRPCService) Encrypt(ctx context.Context, req *kmsapi.EncryptRequest) (*kmsapi.EncryptResponse, error) { + klog.V(4).InfoS("encrypt request received", "id", req.Uid) + + encRes, err := s.kmsService.Encrypt(ctx, req.Uid, req.Plaintext) + if err != nil { + return nil, err + } + + return &kmsapi.EncryptResponse{ + Ciphertext: encRes.Ciphertext, + KeyId: encRes.KeyID, + Annotations: encRes.Annotations, + }, nil +} diff --git a/vendor/k8s.io/kms/pkg/service/interface.go b/vendor/k8s.io/kms/pkg/service/interface.go new file mode 100644 index 0000000000..fad71fa0a3 --- /dev/null +++ b/vendor/k8s.io/kms/pkg/service/interface.go @@ -0,0 +1,50 @@ +/* +Copyright 2023 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 service + +import "context" + +// Service allows encrypting and decrypting data using an external Key Management Service. +type Service interface { + // Decrypt a given bytearray to obtain the original data as bytes. + Decrypt(ctx context.Context, uid string, req *DecryptRequest) ([]byte, error) + // Encrypt bytes to a ciphertext. + Encrypt(ctx context.Context, uid string, data []byte) (*EncryptResponse, error) + // Status returns the status of the KMS. + Status(ctx context.Context) (*StatusResponse, error) +} + +// EncryptResponse is the response from the Envelope service when encrypting data. +type EncryptResponse struct { + Ciphertext []byte + KeyID string + Annotations map[string][]byte +} + +// DecryptRequest is the request to the Envelope service when decrypting data. +type DecryptRequest struct { + Ciphertext []byte + KeyID string + Annotations map[string][]byte +} + +// StatusResponse is the response from the Envelope service when getting the status of the service. +type StatusResponse struct { + Version string + Healthz string + KeyID string +} diff --git a/vendor/k8s.io/kms/pkg/util/util.go b/vendor/k8s.io/kms/pkg/util/util.go new file mode 100644 index 0000000000..008c6a5321 --- /dev/null +++ b/vendor/k8s.io/kms/pkg/util/util.go @@ -0,0 +1,54 @@ +/* +Copyright 2022 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 ( + "fmt" + "net/url" + "strings" +) + +const ( + // unixProtocol is the only supported protocol for remote KMS provider. + unixProtocol = "unix" +) + +// ParseEndpoint parses the endpoint to extract schema, host or path. +func ParseEndpoint(endpoint string) (string, error) { + if len(endpoint) == 0 { + return "", fmt.Errorf("remote KMS provider can't use empty string as endpoint") + } + + u, err := url.Parse(endpoint) + if err != nil { + return "", fmt.Errorf("invalid endpoint %q for remote KMS provider, error: %v", endpoint, err) + } + + if u.Scheme != unixProtocol { + return "", fmt.Errorf("unsupported scheme %q for remote KMS provider", u.Scheme) + } + + // Linux abstract namespace socket - no physical file required + // Warning: Linux Abstract sockets have not concept of ACL (unlike traditional file based sockets). + // However, Linux Abstract sockets are subject to Linux networking namespace, so will only be accessible to + // containers within the same pod (unless host networking is used). + if strings.HasPrefix(u.Path, "/@") { + return strings.TrimPrefix(u.Path, "/"), nil + } + + return u.Path, nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/builder/doc.go b/vendor/k8s.io/kube-openapi/pkg/builder/doc.go new file mode 100644 index 0000000000..c3109067f2 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/builder/doc.go @@ -0,0 +1,20 @@ +/* +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 builder contains code to generate OpenAPI discovery spec (which +// initial version of it also known as Swagger 2.0). +// For more details: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md +package builder diff --git a/vendor/k8s.io/kube-openapi/pkg/builder/openapi.go b/vendor/k8s.io/kube-openapi/pkg/builder/openapi.go new file mode 100644 index 0000000000..98be932cb9 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/builder/openapi.go @@ -0,0 +1,468 @@ +/* +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 builder + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + + restful "github.com/emicklei/go-restful/v3" + + "k8s.io/kube-openapi/pkg/common" + "k8s.io/kube-openapi/pkg/common/restfuladapter" + "k8s.io/kube-openapi/pkg/util" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +const ( + OpenAPIVersion = "2.0" +) + +type openAPI struct { + config *common.Config + swagger *spec.Swagger + protocolList []string + definitions map[string]common.OpenAPIDefinition +} + +// BuildOpenAPISpec builds OpenAPI spec given a list of route containers and common.Config to customize it. +// +// Deprecated: BuildOpenAPISpecFromRoutes should be used instead. +func BuildOpenAPISpec(routeContainers []*restful.WebService, config *common.Config) (*spec.Swagger, error) { + return BuildOpenAPISpecFromRoutes(restfuladapter.AdaptWebServices(routeContainers), config) +} + +// BuildOpenAPISpecFromRoutes builds OpenAPI spec given a list of route containers and common.Config to customize it. +func BuildOpenAPISpecFromRoutes(routeContainers []common.RouteContainer, config *common.Config) (*spec.Swagger, error) { + o := newOpenAPI(config) + err := o.buildPaths(routeContainers) + if err != nil { + return nil, err + } + return o.finalizeSwagger() +} + +// BuildOpenAPIDefinitionsForResource builds a partial OpenAPI spec given a sample object and common.Config to customize it. +func BuildOpenAPIDefinitionsForResource(model interface{}, config *common.Config) (*spec.Definitions, error) { + o := newOpenAPI(config) + // We can discard the return value of toSchema because all we care about is the side effect of calling it. + // All the models created for this resource get added to o.swagger.Definitions + _, err := o.toSchema(util.GetCanonicalTypeName(model)) + if err != nil { + return nil, err + } + swagger, err := o.finalizeSwagger() + if err != nil { + return nil, err + } + return &swagger.Definitions, nil +} + +// BuildOpenAPIDefinitionsForResources returns the OpenAPI spec which includes the definitions for the +// passed type names. +func BuildOpenAPIDefinitionsForResources(config *common.Config, names ...string) (*spec.Swagger, error) { + o := newOpenAPI(config) + // We can discard the return value of toSchema because all we care about is the side effect of calling it. + // All the models created for this resource get added to o.swagger.Definitions + for _, name := range names { + _, err := o.toSchema(name) + if err != nil { + return nil, err + } + } + return o.finalizeSwagger() +} + +// newOpenAPI sets up the openAPI object so we can build the spec. +func newOpenAPI(config *common.Config) openAPI { + o := openAPI{ + config: config, + swagger: &spec.Swagger{ + SwaggerProps: spec.SwaggerProps{ + Swagger: OpenAPIVersion, + Definitions: spec.Definitions{}, + Responses: config.ResponseDefinitions, + Paths: &spec.Paths{Paths: map[string]spec.PathItem{}}, + Info: config.Info, + }, + }, + } + + if o.config.GetOperationIDAndTagsFromRoute == nil { + // Map the deprecated handler to the common interface, if provided. + if o.config.GetOperationIDAndTags != nil { + o.config.GetOperationIDAndTagsFromRoute = func(r common.Route) (string, []string, error) { + restfulRouteAdapter, ok := r.(*restfuladapter.RouteAdapter) + if !ok { + return "", nil, fmt.Errorf("config.GetOperationIDAndTags specified but route is not a restful v1 Route") + } + + return o.config.GetOperationIDAndTags(restfulRouteAdapter.Route) + } + } else { + o.config.GetOperationIDAndTagsFromRoute = func(r common.Route) (string, []string, error) { + return r.OperationName(), nil, nil + } + } + } + + if o.config.GetDefinitionName == nil { + o.config.GetDefinitionName = func(name string) (string, spec.Extensions) { + return name[strings.LastIndex(name, "/")+1:], nil + } + } + o.definitions = o.config.GetDefinitions(func(name string) spec.Ref { + defName, _ := o.config.GetDefinitionName(name) + return spec.MustCreateRef("#/definitions/" + common.EscapeJsonPointer(defName)) + }) + if o.config.CommonResponses == nil { + o.config.CommonResponses = map[int]spec.Response{} + } + return o +} + +// finalizeSwagger is called after the spec is built and returns the final spec. +// NOTE: finalizeSwagger also make changes to the final spec, as specified in the config. +func (o *openAPI) finalizeSwagger() (*spec.Swagger, error) { + if o.config.SecurityDefinitions != nil { + o.swagger.SecurityDefinitions = *o.config.SecurityDefinitions + o.swagger.Security = o.config.DefaultSecurity + } + if o.config.PostProcessSpec != nil { + var err error + o.swagger, err = o.config.PostProcessSpec(o.swagger) + if err != nil { + return nil, err + } + } + + return o.swagger, nil +} + +func (o *openAPI) buildDefinitionRecursively(name string) error { + uniqueName, extensions := o.config.GetDefinitionName(name) + if _, ok := o.swagger.Definitions[uniqueName]; ok { + return nil + } + if item, ok := o.definitions[name]; ok { + schema := spec.Schema{ + VendorExtensible: item.Schema.VendorExtensible, + SchemaProps: item.Schema.SchemaProps, + SwaggerSchemaProps: item.Schema.SwaggerSchemaProps, + } + if extensions != nil { + if schema.Extensions == nil { + schema.Extensions = spec.Extensions{} + } + for k, v := range extensions { + schema.Extensions[k] = v + } + } + if v, ok := item.Schema.Extensions[common.ExtensionV2Schema]; ok { + if v2Schema, isOpenAPISchema := v.(spec.Schema); isOpenAPISchema { + schema = v2Schema + } + } + o.swagger.Definitions[uniqueName] = schema + for _, v := range item.Dependencies { + if err := o.buildDefinitionRecursively(v); err != nil { + return err + } + } + } else { + return fmt.Errorf("cannot find model definition for %v. If you added a new type, you may need to add +k8s:openapi-gen=true to the package or type and run code-gen again", name) + } + return nil +} + +// buildDefinitionForType build a definition for a given type and return a referable name to its definition. +// This is the main function that keep track of definitions used in this spec and is depend on code generated +// by k8s.io/kubernetes/cmd/libs/go2idl/openapi-gen. +func (o *openAPI) buildDefinitionForType(name string) (string, error) { + if err := o.buildDefinitionRecursively(name); err != nil { + return "", err + } + defName, _ := o.config.GetDefinitionName(name) + return "#/definitions/" + common.EscapeJsonPointer(defName), nil +} + +// buildPaths builds OpenAPI paths using go-restful's web services. +func (o *openAPI) buildPaths(routeContainers []common.RouteContainer) error { + pathsToIgnore := util.NewTrie(o.config.IgnorePrefixes) + duplicateOpId := make(map[string]string) + for _, w := range routeContainers { + rootPath := w.RootPath() + if pathsToIgnore.HasPrefix(rootPath) { + continue + } + commonParams, err := o.buildParameters(w.PathParameters()) + if err != nil { + return err + } + for path, routes := range groupRoutesByPath(w.Routes()) { + // go-swagger has special variable definition {$NAME:*} that can only be + // used at the end of the path and it is not recognized by OpenAPI. + if strings.HasSuffix(path, ":*}") { + path = path[:len(path)-3] + "}" + } + if pathsToIgnore.HasPrefix(path) { + continue + } + // Aggregating common parameters make API spec (and generated clients) simpler + inPathCommonParamsMap, err := o.findCommonParameters(routes) + if err != nil { + return err + } + pathItem, exists := o.swagger.Paths.Paths[path] + if exists { + return fmt.Errorf("duplicate webservice route has been found for path: %v", path) + } + pathItem = spec.PathItem{ + PathItemProps: spec.PathItemProps{ + Parameters: make([]spec.Parameter, 0), + }, + } + // add web services's parameters as well as any parameters appears in all ops, as common parameters + pathItem.Parameters = append(pathItem.Parameters, commonParams...) + for _, p := range inPathCommonParamsMap { + pathItem.Parameters = append(pathItem.Parameters, p) + } + sortParameters(pathItem.Parameters) + for _, route := range routes { + op, err := o.buildOperations(route, inPathCommonParamsMap) + sortParameters(op.Parameters) + if err != nil { + return err + } + dpath, exists := duplicateOpId[op.ID] + if exists { + return fmt.Errorf("duplicate Operation ID %v for path %v and %v", op.ID, dpath, path) + } else { + duplicateOpId[op.ID] = path + } + switch strings.ToUpper(route.Method()) { + case "GET": + pathItem.Get = op + case "POST": + pathItem.Post = op + case "HEAD": + pathItem.Head = op + case "PUT": + pathItem.Put = op + case "DELETE": + pathItem.Delete = op + case "OPTIONS": + pathItem.Options = op + case "PATCH": + pathItem.Patch = op + } + } + o.swagger.Paths.Paths[path] = pathItem + } + } + return nil +} + +// buildOperations builds operations for each webservice path +func (o *openAPI) buildOperations(route common.Route, inPathCommonParamsMap map[interface{}]spec.Parameter) (ret *spec.Operation, err error) { + ret = &spec.Operation{ + OperationProps: spec.OperationProps{ + Description: route.Description(), + Consumes: route.Consumes(), + Produces: route.Produces(), + Schemes: o.config.ProtocolList, + Responses: &spec.Responses{ + ResponsesProps: spec.ResponsesProps{ + StatusCodeResponses: make(map[int]spec.Response), + }, + }, + }, + } + for k, v := range route.Metadata() { + if strings.HasPrefix(k, common.ExtensionPrefix) { + if ret.Extensions == nil { + ret.Extensions = spec.Extensions{} + } + ret.Extensions.Add(k, v) + } + } + if ret.ID, ret.Tags, err = o.config.GetOperationIDAndTagsFromRoute(route); err != nil { + return ret, err + } + + // Build responses + for _, resp := range route.StatusCodeResponses() { + ret.Responses.StatusCodeResponses[resp.Code()], err = o.buildResponse(resp.Model(), resp.Message()) + if err != nil { + return ret, err + } + } + // If there is no response but a write sample, assume that write sample is an http.StatusOK response. + if len(ret.Responses.StatusCodeResponses) == 0 && route.ResponsePayloadSample() != nil { + ret.Responses.StatusCodeResponses[http.StatusOK], err = o.buildResponse(route.ResponsePayloadSample(), "OK") + if err != nil { + return ret, err + } + } + for code, resp := range o.config.CommonResponses { + if _, exists := ret.Responses.StatusCodeResponses[code]; !exists { + ret.Responses.StatusCodeResponses[code] = resp + } + } + // If there is still no response, use default response provided. + if len(ret.Responses.StatusCodeResponses) == 0 { + ret.Responses.Default = o.config.DefaultResponse + } + + // Build non-common Parameters + ret.Parameters = make([]spec.Parameter, 0) + for _, param := range route.Parameters() { + if _, isCommon := inPathCommonParamsMap[mapKeyFromParam(param)]; !isCommon { + openAPIParam, err := o.buildParameter(param, route.RequestPayloadSample()) + if err != nil { + return ret, err + } + ret.Parameters = append(ret.Parameters, openAPIParam) + } + } + return ret, nil +} + +func (o *openAPI) buildResponse(model interface{}, description string) (spec.Response, error) { + schema, err := o.toSchema(util.GetCanonicalTypeName(model)) + if err != nil { + return spec.Response{}, err + } + return spec.Response{ + ResponseProps: spec.ResponseProps{ + Description: description, + Schema: schema, + }, + }, nil +} + +func (o *openAPI) findCommonParameters(routes []common.Route) (map[interface{}]spec.Parameter, error) { + commonParamsMap := make(map[interface{}]spec.Parameter, 0) + paramOpsCountByName := make(map[interface{}]int, 0) + paramNameKindToDataMap := make(map[interface{}]common.Parameter, 0) + for _, route := range routes { + routeParamDuplicateMap := make(map[interface{}]bool) + s := "" + params := route.Parameters() + for _, param := range params { + m, _ := json.Marshal(param) + s += string(m) + "\n" + key := mapKeyFromParam(param) + if routeParamDuplicateMap[key] { + msg, _ := json.Marshal(params) + return commonParamsMap, fmt.Errorf("duplicate parameter %v for route %v, %v", param.Name(), string(msg), s) + } + routeParamDuplicateMap[key] = true + paramOpsCountByName[key]++ + paramNameKindToDataMap[key] = param + } + } + for key, count := range paramOpsCountByName { + paramData := paramNameKindToDataMap[key] + if count == len(routes) && paramData.Kind() != common.BodyParameterKind { + openAPIParam, err := o.buildParameter(paramData, nil) + if err != nil { + return commonParamsMap, err + } + commonParamsMap[key] = openAPIParam + } + } + return commonParamsMap, nil +} + +func (o *openAPI) toSchema(name string) (_ *spec.Schema, err error) { + if openAPIType, openAPIFormat := common.OpenAPITypeFormat(name); openAPIType != "" { + return &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{openAPIType}, + Format: openAPIFormat, + }, + }, nil + } else { + ref, err := o.buildDefinitionForType(name) + if err != nil { + return nil, err + } + return &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: spec.MustCreateRef(ref), + }, + }, nil + } +} + +func (o *openAPI) buildParameter(restParam common.Parameter, bodySample interface{}) (ret spec.Parameter, err error) { + ret = spec.Parameter{ + ParamProps: spec.ParamProps{ + Name: restParam.Name(), + Description: restParam.Description(), + Required: restParam.Required(), + }, + } + switch restParam.Kind() { + case common.BodyParameterKind: + if bodySample != nil { + ret.In = "body" + ret.Schema, err = o.toSchema(util.GetCanonicalTypeName(bodySample)) + return ret, err + } else { + // There is not enough information in the body parameter to build the definition. + // Body parameter has a data type that is a short name but we need full package name + // of the type to create a definition. + return ret, fmt.Errorf("restful body parameters are not supported: %v", restParam.DataType()) + } + case common.PathParameterKind: + ret.In = "path" + if !restParam.Required() { + return ret, fmt.Errorf("path parameters should be marked at required for parameter %v", restParam) + } + case common.QueryParameterKind: + ret.In = "query" + case common.HeaderParameterKind: + ret.In = "header" + case common.FormParameterKind: + ret.In = "formData" + default: + return ret, fmt.Errorf("unknown restful operation kind : %v", restParam.Kind()) + } + openAPIType, openAPIFormat := common.OpenAPITypeFormat(restParam.DataType()) + if openAPIType == "" { + return ret, fmt.Errorf("non-body Restful parameter type should be a simple type, but got : %v", restParam.DataType()) + } + ret.Type = openAPIType + ret.Format = openAPIFormat + ret.UniqueItems = !restParam.AllowMultiple() + return ret, nil +} + +func (o *openAPI) buildParameters(restParam []common.Parameter) (ret []spec.Parameter, err error) { + ret = make([]spec.Parameter, len(restParam)) + for i, v := range restParam { + ret[i], err = o.buildParameter(v, nil) + if err != nil { + return ret, err + } + } + return ret, nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/builder/util.go b/vendor/k8s.io/kube-openapi/pkg/builder/util.go new file mode 100644 index 0000000000..3621a4de17 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/builder/util.go @@ -0,0 +1,61 @@ +/* +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 builder + +import ( + "sort" + + "k8s.io/kube-openapi/pkg/common" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +type parameters []spec.Parameter + +func (s parameters) Len() int { return len(s) } +func (s parameters) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// byNameIn used in sorting parameters by Name and In fields. +type byNameIn struct { + parameters +} + +func (s byNameIn) Less(i, j int) bool { + return s.parameters[i].Name < s.parameters[j].Name || (s.parameters[i].Name == s.parameters[j].Name && s.parameters[i].In < s.parameters[j].In) +} + +// SortParameters sorts parameters by Name and In fields. +func sortParameters(p []spec.Parameter) { + sort.Sort(byNameIn{p}) +} + +func groupRoutesByPath(routes []common.Route) map[string][]common.Route { + pathToRoutes := make(map[string][]common.Route) + for _, r := range routes { + pathToRoutes[r.Path()] = append(pathToRoutes[r.Path()], r) + } + return pathToRoutes +} + +func mapKeyFromParam(param common.Parameter) interface{} { + return struct { + Name string + Kind common.ParameterKind + }{ + Name: param.Name(), + Kind: param.Kind(), + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/builder3/openapi.go b/vendor/k8s.io/kube-openapi/pkg/builder3/openapi.go new file mode 100644 index 0000000000..3a8d765f11 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/builder3/openapi.go @@ -0,0 +1,490 @@ +/* +Copyright 2021 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 builder3 + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + + restful "github.com/emicklei/go-restful/v3" + + builderutil "k8s.io/kube-openapi/pkg/builder3/util" + "k8s.io/kube-openapi/pkg/common" + "k8s.io/kube-openapi/pkg/common/restfuladapter" + "k8s.io/kube-openapi/pkg/spec3" + "k8s.io/kube-openapi/pkg/util" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +const ( + OpenAPIVersion = "3.0" +) + +type openAPI struct { + config *common.OpenAPIV3Config + spec *spec3.OpenAPI + definitions map[string]common.OpenAPIDefinition +} + +func groupRoutesByPath(routes []common.Route) map[string][]common.Route { + pathToRoutes := make(map[string][]common.Route) + for _, r := range routes { + pathToRoutes[r.Path()] = append(pathToRoutes[r.Path()], r) + } + return pathToRoutes +} + +func (o *openAPI) buildResponse(model interface{}, description string, content []string) (*spec3.Response, error) { + response := &spec3.Response{ + ResponseProps: spec3.ResponseProps{ + Description: description, + Content: make(map[string]*spec3.MediaType), + }, + } + + s, err := o.toSchema(util.GetCanonicalTypeName(model)) + if err != nil { + return nil, err + } + + for _, contentType := range content { + response.ResponseProps.Content[contentType] = &spec3.MediaType{ + MediaTypeProps: spec3.MediaTypeProps{ + Schema: s, + }, + } + } + return response, nil +} + +func (o *openAPI) buildOperations(route common.Route, inPathCommonParamsMap map[interface{}]*spec3.Parameter) (*spec3.Operation, error) { + ret := &spec3.Operation{ + OperationProps: spec3.OperationProps{ + Description: route.Description(), + Responses: &spec3.Responses{ + ResponsesProps: spec3.ResponsesProps{ + StatusCodeResponses: make(map[int]*spec3.Response), + }, + }, + }, + } + for k, v := range route.Metadata() { + if strings.HasPrefix(k, common.ExtensionPrefix) { + if ret.Extensions == nil { + ret.Extensions = spec.Extensions{} + } + ret.Extensions.Add(k, v) + } + } + + var err error + if ret.OperationId, ret.Tags, err = o.config.GetOperationIDAndTagsFromRoute(route); err != nil { + return ret, err + } + + // Build responses + for _, resp := range route.StatusCodeResponses() { + ret.Responses.StatusCodeResponses[resp.Code()], err = o.buildResponse(resp.Model(), resp.Message(), route.Produces()) + if err != nil { + return ret, err + } + } + + // If there is no response but a write sample, assume that write sample is an http.StatusOK response. + if len(ret.Responses.StatusCodeResponses) == 0 && route.ResponsePayloadSample() != nil { + ret.Responses.StatusCodeResponses[http.StatusOK], err = o.buildResponse(route.ResponsePayloadSample(), "OK", route.Produces()) + if err != nil { + return ret, err + } + } + + for code, resp := range o.config.CommonResponses { + if _, exists := ret.Responses.StatusCodeResponses[code]; !exists { + ret.Responses.StatusCodeResponses[code] = resp + } + } + + if len(ret.Responses.StatusCodeResponses) == 0 { + ret.Responses.Default = o.config.DefaultResponse + } + + params := route.Parameters() + for _, param := range params { + _, isCommon := inPathCommonParamsMap[mapKeyFromParam(param)] + if !isCommon && param.Kind() != common.BodyParameterKind { + openAPIParam, err := o.buildParameter(param) + if err != nil { + return ret, err + } + ret.Parameters = append(ret.Parameters, openAPIParam) + } + } + + body, err := o.buildRequestBody(params, route.Consumes(), route.RequestPayloadSample()) + if err != nil { + return nil, err + } + + if body != nil { + ret.RequestBody = body + } + return ret, nil +} + +func (o *openAPI) buildRequestBody(parameters []common.Parameter, consumes []string, bodySample interface{}) (*spec3.RequestBody, error) { + for _, param := range parameters { + if param.Kind() == common.BodyParameterKind && bodySample != nil { + schema, err := o.toSchema(util.GetCanonicalTypeName(bodySample)) + if err != nil { + return nil, err + } + r := &spec3.RequestBody{ + RequestBodyProps: spec3.RequestBodyProps{ + Content: map[string]*spec3.MediaType{}, + }, + } + for _, consume := range consumes { + r.Content[consume] = &spec3.MediaType{ + MediaTypeProps: spec3.MediaTypeProps{ + Schema: schema, + }, + } + } + return r, nil + } + } + return nil, nil +} + +func newOpenAPI(config *common.Config) openAPI { + o := openAPI{ + config: common.ConvertConfigToV3(config), + spec: &spec3.OpenAPI{ + Version: "3.0.0", + Info: config.Info, + Paths: &spec3.Paths{ + Paths: map[string]*spec3.Path{}, + }, + Components: &spec3.Components{ + Schemas: map[string]*spec.Schema{}, + }, + }, + } + if len(o.config.ResponseDefinitions) > 0 { + o.spec.Components.Responses = make(map[string]*spec3.Response) + + } + for k, response := range o.config.ResponseDefinitions { + o.spec.Components.Responses[k] = response + } + + if len(o.config.SecuritySchemes) > 0 { + o.spec.Components.SecuritySchemes = make(spec3.SecuritySchemes) + + } + for k, securityScheme := range o.config.SecuritySchemes { + o.spec.Components.SecuritySchemes[k] = securityScheme + } + + if o.config.GetOperationIDAndTagsFromRoute == nil { + // Map the deprecated handler to the common interface, if provided. + if o.config.GetOperationIDAndTags != nil { + o.config.GetOperationIDAndTagsFromRoute = func(r common.Route) (string, []string, error) { + restfulRouteAdapter, ok := r.(*restfuladapter.RouteAdapter) + if !ok { + return "", nil, fmt.Errorf("config.GetOperationIDAndTags specified but route is not a restful v1 Route") + } + + return o.config.GetOperationIDAndTags(restfulRouteAdapter.Route) + } + } else { + o.config.GetOperationIDAndTagsFromRoute = func(r common.Route) (string, []string, error) { + return r.OperationName(), nil, nil + } + } + } + + if o.config.GetDefinitionName == nil { + o.config.GetDefinitionName = func(name string) (string, spec.Extensions) { + return name[strings.LastIndex(name, "/")+1:], nil + } + } + + if o.config.Definitions != nil { + o.definitions = o.config.Definitions + } else { + o.definitions = o.config.GetDefinitions(func(name string) spec.Ref { + defName, _ := o.config.GetDefinitionName(name) + return spec.MustCreateRef("#/components/schemas/" + common.EscapeJsonPointer(defName)) + }) + } + + return o +} + +func (o *openAPI) buildOpenAPISpec(webServices []common.RouteContainer) error { + pathsToIgnore := util.NewTrie(o.config.IgnorePrefixes) + for _, w := range webServices { + rootPath := w.RootPath() + if pathsToIgnore.HasPrefix(rootPath) { + continue + } + + commonParams, err := o.buildParameters(w.PathParameters()) + if err != nil { + return err + } + + for path, routes := range groupRoutesByPath(w.Routes()) { + // go-swagger has special variable definition {$NAME:*} that can only be + // used at the end of the path and it is not recognized by OpenAPI. + if strings.HasSuffix(path, ":*}") { + path = path[:len(path)-3] + "}" + } + if pathsToIgnore.HasPrefix(path) { + continue + } + + // Aggregating common parameters make API spec (and generated clients) simpler + inPathCommonParamsMap, err := o.findCommonParameters(routes) + if err != nil { + return err + } + pathItem, exists := o.spec.Paths.Paths[path] + if exists { + return fmt.Errorf("duplicate webservice route has been found for path: %v", path) + } + + pathItem = &spec3.Path{ + PathProps: spec3.PathProps{}, + } + + // add web services's parameters as well as any parameters appears in all ops, as common parameters + pathItem.Parameters = append(pathItem.Parameters, commonParams...) + for _, p := range inPathCommonParamsMap { + pathItem.Parameters = append(pathItem.Parameters, p) + } + sortParameters(pathItem.Parameters) + + for _, route := range routes { + op, _ := o.buildOperations(route, inPathCommonParamsMap) + sortParameters(op.Parameters) + + switch strings.ToUpper(route.Method()) { + case "GET": + pathItem.Get = op + case "POST": + pathItem.Post = op + case "HEAD": + pathItem.Head = op + case "PUT": + pathItem.Put = op + case "DELETE": + pathItem.Delete = op + case "OPTIONS": + pathItem.Options = op + case "PATCH": + pathItem.Patch = op + } + + } + o.spec.Paths.Paths[path] = pathItem + } + } + return nil +} + +// BuildOpenAPISpec builds OpenAPI v3 spec given a list of route containers and common.Config to customize it. +// +// Deprecated: BuildOpenAPISpecFromRoutes should be used instead. +func BuildOpenAPISpec(webServices []*restful.WebService, config *common.Config) (*spec3.OpenAPI, error) { + return BuildOpenAPISpecFromRoutes(restfuladapter.AdaptWebServices(webServices), config) +} + +// BuildOpenAPISpecFromRoutes builds OpenAPI v3 spec given a list of route containers and common.Config to customize it. +func BuildOpenAPISpecFromRoutes(webServices []common.RouteContainer, config *common.Config) (*spec3.OpenAPI, error) { + a := newOpenAPI(config) + err := a.buildOpenAPISpec(webServices) + if err != nil { + return nil, err + } + return a.spec, nil +} + +// BuildOpenAPIDefinitionsForResource builds a partial OpenAPI spec given a sample object and common.Config to customize it. +// BuildOpenAPIDefinitionsForResources returns the OpenAPI spec which includes the definitions for the +// passed type names. +func BuildOpenAPIDefinitionsForResources(config *common.Config, names ...string) (map[string]*spec.Schema, error) { + o := newOpenAPI(config) + // We can discard the return value of toSchema because all we care about is the side effect of calling it. + // All the models created for this resource get added to o.swagger.Definitions + for _, name := range names { + _, err := o.toSchema(name) + if err != nil { + return nil, err + } + } + return o.spec.Components.Schemas, nil +} +func (o *openAPI) findCommonParameters(routes []common.Route) (map[interface{}]*spec3.Parameter, error) { + commonParamsMap := make(map[interface{}]*spec3.Parameter, 0) + paramOpsCountByName := make(map[interface{}]int, 0) + paramNameKindToDataMap := make(map[interface{}]common.Parameter, 0) + for _, route := range routes { + routeParamDuplicateMap := make(map[interface{}]bool) + s := "" + params := route.Parameters() + for _, param := range params { + m, _ := json.Marshal(param) + s += string(m) + "\n" + key := mapKeyFromParam(param) + if routeParamDuplicateMap[key] { + msg, _ := json.Marshal(params) + return commonParamsMap, fmt.Errorf("duplicate parameter %v for route %v, %v", param.Name(), string(msg), s) + } + routeParamDuplicateMap[key] = true + paramOpsCountByName[key]++ + paramNameKindToDataMap[key] = param + } + } + for key, count := range paramOpsCountByName { + paramData := paramNameKindToDataMap[key] + if count == len(routes) && paramData.Kind() != common.BodyParameterKind { + openAPIParam, err := o.buildParameter(paramData) + if err != nil { + return commonParamsMap, err + } + commonParamsMap[key] = openAPIParam + } + } + return commonParamsMap, nil +} + +func (o *openAPI) buildParameters(restParam []common.Parameter) (ret []*spec3.Parameter, err error) { + ret = make([]*spec3.Parameter, len(restParam)) + for i, v := range restParam { + ret[i], err = o.buildParameter(v) + if err != nil { + return ret, err + } + } + return ret, nil +} + +func (o *openAPI) buildParameter(restParam common.Parameter) (ret *spec3.Parameter, err error) { + ret = &spec3.Parameter{ + ParameterProps: spec3.ParameterProps{ + Name: restParam.Name(), + Description: restParam.Description(), + Required: restParam.Required(), + }, + } + switch restParam.Kind() { + case common.BodyParameterKind: + return nil, nil + case common.PathParameterKind: + ret.In = "path" + if !restParam.Required() { + return ret, fmt.Errorf("path parameters should be marked as required for parameter %v", restParam) + } + case common.QueryParameterKind: + ret.In = "query" + case common.HeaderParameterKind: + ret.In = "header" + /* TODO: add support for the cookie param */ + default: + return ret, fmt.Errorf("unsupported restful parameter kind : %v", restParam.Kind()) + } + openAPIType, openAPIFormat := common.OpenAPITypeFormat(restParam.DataType()) + if openAPIType == "" { + return ret, fmt.Errorf("non-body Restful parameter type should be a simple type, but got : %v", restParam.DataType()) + } + + ret.Schema = &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{openAPIType}, + Format: openAPIFormat, + UniqueItems: !restParam.AllowMultiple(), + }, + } + return ret, nil +} + +func (o *openAPI) buildDefinitionRecursively(name string) error { + uniqueName, extensions := o.config.GetDefinitionName(name) + if _, ok := o.spec.Components.Schemas[uniqueName]; ok { + return nil + } + if item, ok := o.definitions[name]; ok { + schema := &spec.Schema{ + VendorExtensible: item.Schema.VendorExtensible, + SchemaProps: item.Schema.SchemaProps, + SwaggerSchemaProps: item.Schema.SwaggerSchemaProps, + } + if extensions != nil { + if schema.Extensions == nil { + schema.Extensions = spec.Extensions{} + } + for k, v := range extensions { + schema.Extensions[k] = v + } + } + // delete the embedded v2 schema if exists, otherwise no-op + delete(schema.VendorExtensible.Extensions, common.ExtensionV2Schema) + schema = builderutil.WrapRefs(schema) + o.spec.Components.Schemas[uniqueName] = schema + for _, v := range item.Dependencies { + if err := o.buildDefinitionRecursively(v); err != nil { + return err + } + } + } else { + return fmt.Errorf("cannot find model definition for %v. If you added a new type, you may need to add +k8s:openapi-gen=true to the package or type and run code-gen again", name) + } + return nil +} + +func (o *openAPI) buildDefinitionForType(name string) (string, error) { + if err := o.buildDefinitionRecursively(name); err != nil { + return "", err + } + defName, _ := o.config.GetDefinitionName(name) + return "#/components/schemas/" + common.EscapeJsonPointer(defName), nil +} + +func (o *openAPI) toSchema(name string) (_ *spec.Schema, err error) { + if openAPIType, openAPIFormat := common.OpenAPITypeFormat(name); openAPIType != "" { + return &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{openAPIType}, + Format: openAPIFormat, + }, + }, nil + } else { + ref, err := o.buildDefinitionForType(name) + if err != nil { + return nil, err + } + return &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: spec.MustCreateRef(ref), + }, + }, nil + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/builder3/util.go b/vendor/k8s.io/kube-openapi/pkg/builder3/util.go new file mode 100644 index 0000000000..a8a90fa15d --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/builder3/util.go @@ -0,0 +1,52 @@ +/* +Copyright 2021 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 builder3 + +import ( + "sort" + + "k8s.io/kube-openapi/pkg/common" + "k8s.io/kube-openapi/pkg/spec3" +) + +func mapKeyFromParam(param common.Parameter) interface{} { + return struct { + Name string + Kind common.ParameterKind + }{ + Name: param.Name(), + Kind: param.Kind(), + } +} + +func (s parameters) Len() int { return len(s) } +func (s parameters) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +type parameters []*spec3.Parameter + +type byNameIn struct { + parameters +} + +func (s byNameIn) Less(i, j int) bool { + return s.parameters[i].Name < s.parameters[j].Name || (s.parameters[i].Name == s.parameters[j].Name && s.parameters[i].In < s.parameters[j].In) +} + +// SortParameters sorts parameters by Name and In fields. +func sortParameters(p []*spec3.Parameter) { + sort.Sort(byNameIn{p}) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/cached/cache.go b/vendor/k8s.io/kube-openapi/pkg/cached/cache.go new file mode 100644 index 0000000000..16e34853af --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/cached/cache.go @@ -0,0 +1,264 @@ +/* +Copyright 2022 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 cache provides a cache mechanism based on etags to lazily +// build, and/or cache results from expensive operation such that those +// operations are not repeated unnecessarily. The operations can be +// created as a tree, and replaced dynamically as needed. +// +// # Dependencies and types of caches +// +// This package uses a source/transform/sink model of caches to build +// the dependency tree, and can be used as follows: +// - [NewSource]: A source cache that recomputes the content every time. +// - [NewStaticSource]: A source cache that always produces the +// same content, it is only called once. +// - [NewTransformer]: A cache that transforms data from one format to +// another. It's only refreshed when the source changes. +// - [NewMerger]: A cache that aggregates multiple caches into one. +// It's only refreshed when the source changes. +// - [Replaceable]: A cache adapter that can be atomically +// replaced with a new one, and saves the previous results in case an +// error pops-up. +// +// # Atomicity +// +// Most of the operations are not atomic/thread-safe, except for +// [Replaceable.Replace] which can be performed while the objects +// are being read. +// +// # Etags +// +// Etags in this library is a cache version identifier. It doesn't +// necessarily strictly match to the semantics of http `etags`, but are +// somewhat inspired from it and function with the same principles. +// Hashing the content is a good way to guarantee that your function is +// never going to be called spuriously. In Kubernetes world, this could +// be a `resourceVersion`, this can be an actual etag, a hash, a UUID +// (if the cache always changes), or even a made-up string when the +// content of the cache never changes. +package cached + +import ( + "fmt" + "sync/atomic" +) + +// Result is the content returned from a call to a cache. It can either +// be created with [NewResultOK] if the call was a success, or +// [NewResultErr] if the call resulted in an error. +type Result[T any] struct { + Data T + Etag string + Err error +} + +// NewResultOK creates a new [Result] for a successful operation. +func NewResultOK[T any](data T, etag string) Result[T] { + return Result[T]{ + Data: data, + Etag: etag, + } +} + +// NewResultErr creates a new [Result] when an error has happened. +func NewResultErr[T any](err error) Result[T] { + return Result[T]{ + Err: err, + } +} + +// Result can be treated as a [Data] if necessary. +func (r Result[T]) Get() Result[T] { + return r +} + +// Data is a cache that performs an action whose result data will be +// cached. It also returns an "etag" identifier to version the cache, so +// that the caller can know if they have the most recent version of the +// cache (and can decide to cache some operation based on that). +// +// The [NewMerger] and [NewTransformer] automatically handle +// that for you by checking if the etag is updated before calling the +// merging or transforming function. +type Data[T any] interface { + // Returns the cached data, as well as an "etag" to identify the + // version of the cache, or an error if something happened. + Get() Result[T] +} + +// T is the source type, V is the destination type. +type merger[K comparable, T, V any] struct { + mergeFn func(map[K]Result[T]) Result[V] + caches map[K]Data[T] + cacheResults map[K]Result[T] + result Result[V] +} + +// NewMerger creates a new merge cache, a cache that merges the result +// of other caches. The function only gets called if any of the +// dependency has changed. +// +// If any of the dependency returned an error before, or any of the +// dependency returned an error this time, or if the mergeFn failed +// before, then the function is reran. +// +// The caches and results are mapped by K so that associated data can be +// retrieved. The map of dependencies can not be modified after +// creation, and a new merger should be created (and probably replaced +// using a [Replaceable]). +// +// Note that this assumes there is no "partial" merge, the merge +// function will remerge all the dependencies together everytime. Since +// the list of dependencies is constant, there is no way to save some +// partial merge information either. +func NewMerger[K comparable, T, V any](mergeFn func(results map[K]Result[T]) Result[V], caches map[K]Data[T]) Data[V] { + return &merger[K, T, V]{ + mergeFn: mergeFn, + caches: caches, + } +} + +func (c *merger[K, T, V]) prepareResults() map[K]Result[T] { + cacheResults := make(map[K]Result[T], len(c.caches)) + for key, cache := range c.caches { + cacheResults[key] = cache.Get() + } + return cacheResults +} + +// Rerun if: +// - The last run resulted in an error +// - Any of the dependency previously returned an error +// - Any of the dependency just returned an error +// - Any of the dependency's etag changed +func (c *merger[K, T, V]) needsRunning(results map[K]Result[T]) bool { + if c.cacheResults == nil { + return true + } + if c.result.Err != nil { + return true + } + if len(results) != len(c.cacheResults) { + panic(fmt.Errorf("invalid number of results: %v (expected %v)", len(results), len(c.cacheResults))) + } + for key, oldResult := range c.cacheResults { + newResult, ok := results[key] + if !ok { + panic(fmt.Errorf("unknown cache entry: %v", key)) + } + + if newResult.Etag != oldResult.Etag || newResult.Err != nil || oldResult.Err != nil { + return true + } + } + return false +} + +func (c *merger[K, T, V]) Get() Result[V] { + cacheResults := c.prepareResults() + if c.needsRunning(cacheResults) { + c.cacheResults = cacheResults + c.result = c.mergeFn(c.cacheResults) + } + return c.result +} + +type transformerCacheKeyType struct{} + +// NewTransformer creates a new cache that transforms the result of +// another cache. The transformFn will only be called if the source +// cache has updated the output, otherwise, the cached result will be +// returned. +// +// If the dependency returned an error before, or it returns an error +// this time, or if the transformerFn failed before, the function is +// reran. +func NewTransformer[T, V any](transformerFn func(Result[T]) Result[V], source Data[T]) Data[V] { + return NewMerger(func(caches map[transformerCacheKeyType]Result[T]) Result[V] { + cache, ok := caches[transformerCacheKeyType{}] + if len(caches) != 1 || !ok { + panic(fmt.Errorf("invalid cache for transformer cache: %v", caches)) + } + return transformerFn(cache) + }, map[transformerCacheKeyType]Data[T]{ + {}: source, + }) +} + +// NewSource creates a new cache that generates some data. This +// will always be called since we don't know the origin of the data and +// if it needs to be updated or not. +func NewSource[T any](sourceFn func() Result[T]) Data[T] { + c := source[T](sourceFn) + return &c +} + +type source[T any] func() Result[T] + +func (c *source[T]) Get() Result[T] { + return (*c)() +} + +// NewStaticSource creates a new cache that always generates the +// same data. This will only be called once (lazily). +func NewStaticSource[T any](staticFn func() Result[T]) Data[T] { + return &static[T]{ + fn: staticFn, + } +} + +type static[T any] struct { + fn func() Result[T] + result *Result[T] +} + +func (c *static[T]) Get() Result[T] { + if c.result == nil { + result := c.fn() + c.result = &result + } + return *c.result +} + +// Replaceable is a cache that carries the result even when the +// cache is replaced. The cache can be replaced atomically (without any +// lock held). This is the type that should typically be stored in +// structs. +type Replaceable[T any] struct { + cache atomic.Pointer[Data[T]] + result *Result[T] +} + +// Get retrieves the data from the underlying source. [Replaceable] +// implements the [Data] interface itself. This is a pass-through +// that calls the most recent underlying cache. If the cache fails but +// previously had returned a success, that success will be returned +// instead. If the cache fails but we never returned a success, that +// failure is returned. +func (c *Replaceable[T]) Get() Result[T] { + result := (*c.cache.Load()).Get() + if result.Err != nil && c.result != nil && c.result.Err == nil { + return *c.result + } + c.result = &result + return *c.result +} + +// Replace changes the cache in a thread-safe way. +func (c *Replaceable[T]) Replace(cache Data[T]) { + c.cache.Swap(&cache) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/common/common.go b/vendor/k8s.io/kube-openapi/pkg/common/common.go index 24f2b0e889..1a6c12e17a 100644 --- a/vendor/k8s.io/kube-openapi/pkg/common/common.go +++ b/vendor/k8s.io/kube-openapi/pkg/common/common.go @@ -246,38 +246,42 @@ var schemaTypeFormatMap = map[string]typeInfo{ // the spec does not need to be simple type,format) or can even return a simple type,format (e.g. IntOrString). For simple // type formats, the benefit of adding OpenAPIDefinitionGetter interface is to keep both type and property documentation. // Example: -// type Sample struct { -// ... -// // port of the server -// port IntOrString -// ... -// } +// +// type Sample struct { +// ... +// // port of the server +// port IntOrString +// ... +// } +// // // IntOrString documentation... // type IntOrString { ... } // // Adding IntOrString to this function: -// "port" : { -// format: "string", -// type: "int-or-string", -// Description: "port of the server" -// } +// +// "port" : { +// format: "string", +// type: "int-or-string", +// Description: "port of the server" +// } // // Implement OpenAPIDefinitionGetter for IntOrString: // -// "port" : { -// $Ref: "#/definitions/IntOrString" -// Description: "port of the server" -// } +// "port" : { +// $Ref: "#/definitions/IntOrString" +// Description: "port of the server" +// } +// // ... // definitions: -// { -// "IntOrString": { -// format: "string", -// type: "int-or-string", -// Description: "IntOrString documentation..." // new -// } -// } // +// { +// "IntOrString": { +// format: "string", +// type: "int-or-string", +// Description: "IntOrString documentation..." // new +// } +// } func OpenAPITypeFormat(typeName string) (string, string) { mapped, ok := schemaTypeFormatMap[typeName] if !ok { diff --git a/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/adapter.go b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/adapter.go new file mode 100644 index 0000000000..932b84a01f --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/adapter.go @@ -0,0 +1,15 @@ +package restfuladapter + +import ( + "github.com/emicklei/go-restful/v3" + "k8s.io/kube-openapi/pkg/common" +) + +// AdaptWebServices adapts a slice of restful.WebService into the common interfaces. +func AdaptWebServices(webServices []*restful.WebService) []common.RouteContainer { + var containers []common.RouteContainer + for _, ws := range webServices { + containers = append(containers, &WebServiceAdapter{ws}) + } + return containers +} diff --git a/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/param_adapter.go b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/param_adapter.go new file mode 100644 index 0000000000..6805dd6c7f --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/param_adapter.go @@ -0,0 +1,54 @@ +package restfuladapter + +import ( + "encoding/json" + "github.com/emicklei/go-restful/v3" + "k8s.io/kube-openapi/pkg/common" +) + +var _ common.Parameter = &ParamAdapter{} + +type ParamAdapter struct { + Param *restful.Parameter +} + +func (r *ParamAdapter) MarshalJSON() ([]byte, error) { + return json.Marshal(r.Param) +} + +func (r *ParamAdapter) Name() string { + return r.Param.Data().Name +} + +func (r *ParamAdapter) Description() string { + return r.Param.Data().Description +} + +func (r *ParamAdapter) Required() bool { + return r.Param.Data().Required +} + +func (r *ParamAdapter) Kind() common.ParameterKind { + switch r.Param.Kind() { + case restful.PathParameterKind: + return common.PathParameterKind + case restful.QueryParameterKind: + return common.QueryParameterKind + case restful.BodyParameterKind: + return common.BodyParameterKind + case restful.HeaderParameterKind: + return common.HeaderParameterKind + case restful.FormParameterKind: + return common.FormParameterKind + default: + return common.UnknownParameterKind + } +} + +func (r *ParamAdapter) DataType() string { + return r.Param.Data().DataType +} + +func (r *ParamAdapter) AllowMultiple() bool { + return r.Param.Data().AllowMultiple +} diff --git a/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/response_error_adapter.go b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/response_error_adapter.go new file mode 100644 index 0000000000..92556398eb --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/response_error_adapter.go @@ -0,0 +1,25 @@ +package restfuladapter + +import ( + "github.com/emicklei/go-restful/v3" + "k8s.io/kube-openapi/pkg/common" +) + +var _ common.StatusCodeResponse = &ResponseErrorAdapter{} + +// ResponseErrorAdapter adapts a restful.ResponseError to common.StatusCodeResponse. +type ResponseErrorAdapter struct { + Err *restful.ResponseError +} + +func (r *ResponseErrorAdapter) Message() string { + return r.Err.Message +} + +func (r *ResponseErrorAdapter) Model() interface{} { + return r.Err.Model +} + +func (r *ResponseErrorAdapter) Code() int { + return r.Err.Code +} diff --git a/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/route_adapter.go b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/route_adapter.go new file mode 100644 index 0000000000..c7ba3a5644 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/route_adapter.go @@ -0,0 +1,68 @@ +package restfuladapter + +import ( + "github.com/emicklei/go-restful/v3" + "k8s.io/kube-openapi/pkg/common" +) + +var _ common.Route = &RouteAdapter{} + +// RouteAdapter adapts a restful.Route to common.Route. +type RouteAdapter struct { + Route *restful.Route +} + +func (r *RouteAdapter) StatusCodeResponses() []common.StatusCodeResponse { + // go-restful uses the ResponseErrors field to contain both error and regular responses. + var responses []common.StatusCodeResponse + for _, res := range r.Route.ResponseErrors { + localRes := res + responses = append(responses, &ResponseErrorAdapter{&localRes}) + } + + return responses +} + +func (r *RouteAdapter) OperationName() string { + return r.Route.Operation +} + +func (r *RouteAdapter) Method() string { + return r.Route.Method +} + +func (r *RouteAdapter) Path() string { + return r.Route.Path +} + +func (r *RouteAdapter) Parameters() []common.Parameter { + var params []common.Parameter + for _, rParam := range r.Route.ParameterDocs { + params = append(params, &ParamAdapter{rParam}) + } + return params +} + +func (r *RouteAdapter) Description() string { + return r.Route.Doc +} + +func (r *RouteAdapter) Consumes() []string { + return r.Route.Consumes +} + +func (r *RouteAdapter) Produces() []string { + return r.Route.Produces +} + +func (r *RouteAdapter) Metadata() map[string]interface{} { + return r.Route.Metadata +} + +func (r *RouteAdapter) RequestPayloadSample() interface{} { + return r.Route.ReadSample +} + +func (r *RouteAdapter) ResponsePayloadSample() interface{} { + return r.Route.WriteSample +} diff --git a/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/webservice_adapter.go b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/webservice_adapter.go new file mode 100644 index 0000000000..995586538d --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/webservice_adapter.go @@ -0,0 +1,34 @@ +package restfuladapter + +import ( + "github.com/emicklei/go-restful/v3" + "k8s.io/kube-openapi/pkg/common" +) + +var _ common.RouteContainer = &WebServiceAdapter{} + +// WebServiceAdapter adapts a restful.WebService to common.RouteContainer. +type WebServiceAdapter struct { + WebService *restful.WebService +} + +func (r *WebServiceAdapter) RootPath() string { + return r.WebService.RootPath() +} + +func (r *WebServiceAdapter) PathParameters() []common.Parameter { + var params []common.Parameter + for _, rParam := range r.WebService.PathParameters() { + params = append(params, &ParamAdapter{rParam}) + } + return params +} + +func (r *WebServiceAdapter) Routes() []common.Route { + var routes []common.Route + for _, rRoute := range r.WebService.Routes() { + localRoute := rRoute + routes = append(routes, &RouteAdapter{&localRoute}) + } + return routes +} diff --git a/vendor/k8s.io/kube-openapi/pkg/handler/default_pruning.go b/vendor/k8s.io/kube-openapi/pkg/handler/default_pruning.go new file mode 100644 index 0000000000..53bd9a640f --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/handler/default_pruning.go @@ -0,0 +1,208 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package handler + +import "k8s.io/kube-openapi/pkg/validation/spec" + +// PruneDefaults remove all the defaults recursively from all the +// schemas in the definitions, and does not modify the definitions in +// place. +func PruneDefaults(definitions spec.Definitions) spec.Definitions { + definitionsCloned := false + for k, v := range definitions { + if s := PruneDefaultsSchema(&v); s != &v { + if !definitionsCloned { + definitionsCloned = true + orig := definitions + definitions = make(spec.Definitions, len(orig)) + for k2, v2 := range orig { + definitions[k2] = v2 + } + } + definitions[k] = *s + } + } + return definitions +} + +// PruneDefaultsSchema remove all the defaults recursively from the +// schema in place. +func PruneDefaultsSchema(schema *spec.Schema) *spec.Schema { + if schema == nil { + return nil + } + + orig := schema + clone := func() { + if orig == schema { + schema = &spec.Schema{} + *schema = *orig + } + } + + if schema.Default != nil { + clone() + schema.Default = nil + } + + definitionsCloned := false + for k, v := range schema.Definitions { + if s := PruneDefaultsSchema(&v); s != &v { + if !definitionsCloned { + definitionsCloned = true + clone() + schema.Definitions = make(spec.Definitions, len(orig.Definitions)) + for k2, v2 := range orig.Definitions { + schema.Definitions[k2] = v2 + } + } + schema.Definitions[k] = *s + } + } + + propertiesCloned := false + for k, v := range schema.Properties { + if s := PruneDefaultsSchema(&v); s != &v { + if !propertiesCloned { + propertiesCloned = true + clone() + schema.Properties = make(map[string]spec.Schema, len(orig.Properties)) + for k2, v2 := range orig.Properties { + schema.Properties[k2] = v2 + } + } + schema.Properties[k] = *s + } + } + + patternPropertiesCloned := false + for k, v := range schema.PatternProperties { + if s := PruneDefaultsSchema(&v); s != &v { + if !patternPropertiesCloned { + patternPropertiesCloned = true + clone() + schema.PatternProperties = make(map[string]spec.Schema, len(orig.PatternProperties)) + for k2, v2 := range orig.PatternProperties { + schema.PatternProperties[k2] = v2 + } + } + schema.PatternProperties[k] = *s + } + } + + dependenciesCloned := false + for k, v := range schema.Dependencies { + if s := PruneDefaultsSchema(v.Schema); s != v.Schema { + if !dependenciesCloned { + dependenciesCloned = true + clone() + schema.Dependencies = make(spec.Dependencies, len(orig.Dependencies)) + for k2, v2 := range orig.Dependencies { + schema.Dependencies[k2] = v2 + } + } + v.Schema = s + schema.Dependencies[k] = v + } + } + + allOfCloned := false + for i := range schema.AllOf { + if s := PruneDefaultsSchema(&schema.AllOf[i]); s != &schema.AllOf[i] { + if !allOfCloned { + allOfCloned = true + clone() + schema.AllOf = make([]spec.Schema, len(orig.AllOf)) + copy(schema.AllOf, orig.AllOf) + } + schema.AllOf[i] = *s + } + } + + anyOfCloned := false + for i := range schema.AnyOf { + if s := PruneDefaultsSchema(&schema.AnyOf[i]); s != &schema.AnyOf[i] { + if !anyOfCloned { + anyOfCloned = true + clone() + schema.AnyOf = make([]spec.Schema, len(orig.AnyOf)) + copy(schema.AnyOf, orig.AnyOf) + } + schema.AnyOf[i] = *s + } + } + + oneOfCloned := false + for i := range schema.OneOf { + if s := PruneDefaultsSchema(&schema.OneOf[i]); s != &schema.OneOf[i] { + if !oneOfCloned { + oneOfCloned = true + clone() + schema.OneOf = make([]spec.Schema, len(orig.OneOf)) + copy(schema.OneOf, orig.OneOf) + } + schema.OneOf[i] = *s + } + } + + if schema.Not != nil { + if s := PruneDefaultsSchema(schema.Not); s != schema.Not { + clone() + schema.Not = s + } + } + + if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil { + if s := PruneDefaultsSchema(schema.AdditionalProperties.Schema); s != schema.AdditionalProperties.Schema { + clone() + schema.AdditionalProperties = &spec.SchemaOrBool{Schema: s, Allows: schema.AdditionalProperties.Allows} + } + } + + if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil { + if s := PruneDefaultsSchema(schema.AdditionalItems.Schema); s != schema.AdditionalItems.Schema { + clone() + schema.AdditionalItems = &spec.SchemaOrBool{Schema: s, Allows: schema.AdditionalItems.Allows} + } + } + + if schema.Items != nil { + if schema.Items.Schema != nil { + if s := PruneDefaultsSchema(schema.Items.Schema); s != schema.Items.Schema { + clone() + schema.Items = &spec.SchemaOrArray{Schema: s} + } + } else { + itemsCloned := false + for i := range schema.Items.Schemas { + if s := PruneDefaultsSchema(&schema.Items.Schemas[i]); s != &schema.Items.Schemas[i] { + if !itemsCloned { + clone() + schema.Items = &spec.SchemaOrArray{ + Schemas: make([]spec.Schema, len(orig.Items.Schemas)), + } + itemsCloned = true + copy(schema.Items.Schemas, orig.Items.Schemas) + } + schema.Items.Schemas[i] = *s + } + } + } + } + + return schema +} diff --git a/vendor/k8s.io/kube-openapi/pkg/handler/handler.go b/vendor/k8s.io/kube-openapi/pkg/handler/handler.go new file mode 100644 index 0000000000..84e9026465 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/handler/handler.go @@ -0,0 +1,211 @@ +/* +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 handler + +import ( + "bytes" + "crypto/sha512" + "fmt" + "net/http" + "strconv" + "time" + + "github.com/NYTimes/gziphandler" + "github.com/emicklei/go-restful/v3" + "github.com/golang/protobuf/proto" + openapi_v2 "github.com/google/gnostic/openapiv2" + "github.com/google/uuid" + "github.com/munnerz/goautoneg" + klog "k8s.io/klog/v2" + "k8s.io/kube-openapi/pkg/builder" + "k8s.io/kube-openapi/pkg/cached" + "k8s.io/kube-openapi/pkg/common" + "k8s.io/kube-openapi/pkg/common/restfuladapter" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +const ( + subTypeProtobufDeprecated = "com.github.proto-openapi.spec.v2@v1.0+protobuf" + subTypeProtobuf = "com.github.proto-openapi.spec.v2.v1.0+protobuf" + subTypeJSON = "json" +) + +func computeETag(data []byte) string { + if data == nil { + return "" + } + return fmt.Sprintf("%X", sha512.Sum512(data)) +} + +type timedSpec struct { + spec []byte + lastModified time.Time +} + +// OpenAPIService is the service responsible for serving OpenAPI spec. It has +// the ability to safely change the spec while serving it. +type OpenAPIService struct { + specCache cached.Replaceable[*spec.Swagger] + jsonCache cached.Data[timedSpec] + protoCache cached.Data[timedSpec] +} + +// NewOpenAPIService builds an OpenAPIService starting with the given spec. +func NewOpenAPIService(swagger *spec.Swagger) *OpenAPIService { + return NewOpenAPIServiceLazy(cached.NewResultOK(swagger, uuid.New().String())) +} + +// NewOpenAPIServiceLazy builds an OpenAPIService from lazy spec. +func NewOpenAPIServiceLazy(swagger cached.Data[*spec.Swagger]) *OpenAPIService { + o := &OpenAPIService{} + o.UpdateSpecLazy(swagger) + + o.jsonCache = cached.NewTransformer[*spec.Swagger](func(result cached.Result[*spec.Swagger]) cached.Result[timedSpec] { + if result.Err != nil { + return cached.NewResultErr[timedSpec](result.Err) + } + json, err := result.Data.MarshalJSON() + if err != nil { + return cached.NewResultErr[timedSpec](err) + } + return cached.NewResultOK(timedSpec{spec: json, lastModified: time.Now()}, computeETag(json)) + }, &o.specCache) + o.protoCache = cached.NewTransformer(func(result cached.Result[timedSpec]) cached.Result[timedSpec] { + if result.Err != nil { + return cached.NewResultErr[timedSpec](result.Err) + } + proto, err := ToProtoBinary(result.Data.spec) + if err != nil { + return cached.NewResultErr[timedSpec](err) + } + // We can re-use the same etag as json because of the Vary header. + return cached.NewResultOK(timedSpec{spec: proto, lastModified: result.Data.lastModified}, result.Etag) + }, o.jsonCache) + return o +} + +func (o *OpenAPIService) getSwaggerBytes() (timedSpec, string, error) { + result := o.jsonCache.Get() + return result.Data, result.Etag, result.Err +} + +func (o *OpenAPIService) getSwaggerPbBytes() (timedSpec, string, error) { + result := o.protoCache.Get() + return result.Data, result.Etag, result.Err +} + +func (o *OpenAPIService) UpdateSpec(swagger *spec.Swagger) error { + o.UpdateSpecLazy(cached.NewResultOK(swagger, uuid.New().String())) + return nil +} + +func (o *OpenAPIService) UpdateSpecLazy(swagger cached.Data[*spec.Swagger]) { + o.specCache.Replace(swagger) +} + +func ToProtoBinary(json []byte) ([]byte, error) { + document, err := openapi_v2.ParseDocument(json) + if err != nil { + return nil, err + } + return proto.Marshal(document) +} + +// RegisterOpenAPIVersionedService registers a handler to provide access to provided swagger spec. +// +// Deprecated: use OpenAPIService.RegisterOpenAPIVersionedService instead. +func RegisterOpenAPIVersionedService(spec *spec.Swagger, servePath string, handler common.PathHandler) (*OpenAPIService, error) { + o := NewOpenAPIService(spec) + return o, o.RegisterOpenAPIVersionedService(servePath, handler) +} + +// RegisterOpenAPIVersionedService registers a handler to provide access to provided swagger spec. +func (o *OpenAPIService) RegisterOpenAPIVersionedService(servePath string, handler common.PathHandler) error { + accepted := []struct { + Type string + SubType string + ReturnedContentType string + GetDataAndEtag cached.Data[timedSpec] + }{ + {"application", subTypeJSON, "application/" + subTypeJSON, o.jsonCache}, + {"application", subTypeProtobufDeprecated, "application/" + subTypeProtobuf, o.protoCache}, + {"application", subTypeProtobuf, "application/" + subTypeProtobuf, o.protoCache}, + } + + handler.Handle(servePath, gziphandler.GzipHandler(http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + decipherableFormats := r.Header.Get("Accept") + if decipherableFormats == "" { + decipherableFormats = "*/*" + } + clauses := goautoneg.ParseAccept(decipherableFormats) + w.Header().Add("Vary", "Accept") + for _, clause := range clauses { + for _, accepts := range accepted { + if clause.Type != accepts.Type && clause.Type != "*" { + continue + } + if clause.SubType != accepts.SubType && clause.SubType != "*" { + continue + } + // serve the first matching media type in the sorted clause list + result := accepts.GetDataAndEtag.Get() + if result.Err != nil { + klog.Errorf("Error in OpenAPI handler: %s", result.Err) + // only return a 503 if we have no older cache data to serve + if result.Data.spec == nil { + w.WriteHeader(http.StatusServiceUnavailable) + return + } + } + // Set Content-Type header in the reponse + w.Header().Set("Content-Type", accepts.ReturnedContentType) + + // ETag must be enclosed in double quotes: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag + w.Header().Set("Etag", strconv.Quote(result.Etag)) + // ServeContent will take care of caching using eTag. + http.ServeContent(w, r, servePath, result.Data.lastModified, bytes.NewReader(result.Data.spec)) + return + } + } + // Return 406 for not acceptable format + w.WriteHeader(406) + return + }), + )) + + return nil +} + +// BuildAndRegisterOpenAPIVersionedService builds the spec and registers a handler to provide access to it. +// Use this method if your OpenAPI spec is static. If you want to update the spec, use BuildOpenAPISpec then RegisterOpenAPIVersionedService. +// +// Deprecated: BuildAndRegisterOpenAPIVersionedServiceFromRoutes should be used instead. +func BuildAndRegisterOpenAPIVersionedService(servePath string, webServices []*restful.WebService, config *common.Config, handler common.PathHandler) (*OpenAPIService, error) { + return BuildAndRegisterOpenAPIVersionedServiceFromRoutes(servePath, restfuladapter.AdaptWebServices(webServices), config, handler) +} + +// BuildAndRegisterOpenAPIVersionedServiceFromRoutes builds the spec and registers a handler to provide access to it. +// Use this method if your OpenAPI spec is static. If you want to update the spec, use BuildOpenAPISpec then RegisterOpenAPIVersionedService. +func BuildAndRegisterOpenAPIVersionedServiceFromRoutes(servePath string, routeContainers []common.RouteContainer, config *common.Config, handler common.PathHandler) (*OpenAPIService, error) { + spec, err := builder.BuildOpenAPISpecFromRoutes(routeContainers, config) + if err != nil { + return nil, err + } + o := NewOpenAPIService(spec) + return o, o.RegisterOpenAPIVersionedService(servePath, handler) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/handler3/handler.go b/vendor/k8s.io/kube-openapi/pkg/handler3/handler.go index ec4adcdec2..66b7a68da6 100644 --- a/vendor/k8s.io/kube-openapi/pkg/handler3/handler.go +++ b/vendor/k8s.io/kube-openapi/pkg/handler3/handler.go @@ -21,11 +21,9 @@ import ( "crypto/sha512" "encoding/json" "fmt" - "mime" "net/http" "net/url" "path" - "sort" "strconv" "strings" "sync" @@ -33,23 +31,18 @@ import ( "github.com/golang/protobuf/proto" openapi_v3 "github.com/google/gnostic/openapiv3" + "github.com/google/uuid" "github.com/munnerz/goautoneg" + "k8s.io/klog/v2" + "k8s.io/kube-openapi/pkg/cached" "k8s.io/kube-openapi/pkg/common" - "k8s.io/kube-openapi/pkg/internal/handler" "k8s.io/kube-openapi/pkg/spec3" - "k8s.io/kube-openapi/pkg/validation/spec" ) const ( - jsonExt = ".json" - - mimeJson = "application/json" - // TODO(mehdy): change @68f4ded to a version tag when gnostic add version tags. - mimePb = "application/com.github.googleapis.gnostic.OpenAPIv3@68f4ded+protobuf" - mimePbGz = "application/x-gzip" - - subTypeProtobuf = "com.github.proto-openapi.spec.v3@v1.0+protobuf" - subTypeJSON = "json" + subTypeProtobufDeprecated = "com.github.proto-openapi.spec.v3@v1.0+protobuf" + subTypeProtobuf = "com.github.proto-openapi.spec.v3.v1.0+protobuf" + subTypeJSON = "json" ) // OpenAPIV3Discovery is the format of the Discovery document for OpenAPI V3 @@ -65,29 +58,63 @@ type OpenAPIV3DiscoveryGroupVersion struct { ServerRelativeURL string `json:"serverRelativeURL"` } -// OpenAPIService is the service responsible for serving OpenAPI spec. It has -// the ability to safely change the spec while serving it. -type OpenAPIService struct { - // rwMutex protects All members of this service. - rwMutex sync.RWMutex +func ToV3ProtoBinary(json []byte) ([]byte, error) { + document, err := openapi_v3.ParseDocument(json) + if err != nil { + return nil, err + } + return proto.Marshal(document) +} + +type timedSpec struct { + spec []byte lastModified time.Time - v3Schema map[string]*OpenAPIV3Group } -type OpenAPIV3Group struct { - rwMutex sync.RWMutex +// This type is protected by the lock on OpenAPIService. +type openAPIV3Group struct { + specCache cached.Replaceable[*spec3.OpenAPI] + pbCache cached.Data[timedSpec] + jsonCache cached.Data[timedSpec] +} - lastModified time.Time +func newOpenAPIV3Group() *openAPIV3Group { + o := &openAPIV3Group{} + o.jsonCache = cached.NewTransformer[*spec3.OpenAPI](func(result cached.Result[*spec3.OpenAPI]) cached.Result[timedSpec] { + if result.Err != nil { + return cached.NewResultErr[timedSpec](result.Err) + } + json, err := json.Marshal(result.Data) + if err != nil { + return cached.NewResultErr[timedSpec](err) + } + return cached.NewResultOK(timedSpec{spec: json, lastModified: time.Now()}, computeETag(json)) + }, &o.specCache) + o.pbCache = cached.NewTransformer(func(result cached.Result[timedSpec]) cached.Result[timedSpec] { + if result.Err != nil { + return cached.NewResultErr[timedSpec](result.Err) + } + proto, err := ToV3ProtoBinary(result.Data.spec) + if err != nil { + return cached.NewResultErr[timedSpec](err) + } + return cached.NewResultOK(timedSpec{spec: proto, lastModified: result.Data.lastModified}, result.Etag) + }, o.jsonCache) + return o +} - pbCache handler.HandlerCache - jsonCache handler.HandlerCache - etagCache handler.HandlerCache +func (o *openAPIV3Group) UpdateSpec(openapi cached.Data[*spec3.OpenAPI]) { + o.specCache.Replace(openapi) } -func init() { - mime.AddExtensionType(".json", mimeJson) - mime.AddExtensionType(".pb-v1", mimePb) - mime.AddExtensionType(".gz", mimePbGz) +// OpenAPIService is the service responsible for serving OpenAPI spec. It has +// the ability to safely change the spec while serving it. +type OpenAPIService struct { + // Mutex protects the schema map. + mutex sync.Mutex + v3Schema map[string]*openAPIV3Group + + discoveryCache cached.Replaceable[timedSpec] } func computeETag(data []byte) string { @@ -106,92 +133,90 @@ func constructServerRelativeURL(gvString, etag string) string { } // NewOpenAPIService builds an OpenAPIService starting with the given spec. -func NewOpenAPIService(spec *spec.Swagger) (*OpenAPIService, error) { +func NewOpenAPIService() *OpenAPIService { o := &OpenAPIService{} - o.v3Schema = make(map[string]*OpenAPIV3Group) - return o, nil + o.v3Schema = make(map[string]*openAPIV3Group) + // We're not locked because we haven't shared the structure yet. + o.discoveryCache.Replace(o.buildDiscoveryCacheLocked()) + return o } -func (o *OpenAPIService) getGroupBytes() ([]byte, error) { - o.rwMutex.RLock() - defer o.rwMutex.RUnlock() - keys := make([]string, len(o.v3Schema)) - i := 0 - for k := range o.v3Schema { - keys[i] = k - i++ +func (o *OpenAPIService) buildDiscoveryCacheLocked() cached.Data[timedSpec] { + caches := make(map[string]cached.Data[timedSpec], len(o.v3Schema)) + for gvName, group := range o.v3Schema { + caches[gvName] = group.jsonCache } - - sort.Strings(keys) - discovery := &OpenAPIV3Discovery{Paths: make(map[string]OpenAPIV3DiscoveryGroupVersion)} - for gvString, groupVersion := range o.v3Schema { - etagBytes, err := groupVersion.etagCache.Get() - if err != nil { - return nil, err + return cached.NewMerger(func(results map[string]cached.Result[timedSpec]) cached.Result[timedSpec] { + discovery := &OpenAPIV3Discovery{Paths: make(map[string]OpenAPIV3DiscoveryGroupVersion)} + for gvName, result := range results { + if result.Err != nil { + return cached.NewResultErr[timedSpec](result.Err) + } + discovery.Paths[gvName] = OpenAPIV3DiscoveryGroupVersion{ + ServerRelativeURL: constructServerRelativeURL(gvName, result.Etag), + } } - discovery.Paths[gvString] = OpenAPIV3DiscoveryGroupVersion{ - ServerRelativeURL: constructServerRelativeURL(gvString, string(etagBytes)), + j, err := json.Marshal(discovery) + if err != nil { + return cached.NewResultErr[timedSpec](err) } - } - j, err := json.Marshal(discovery) - if err != nil { - return nil, err - } - return j, nil + return cached.NewResultOK(timedSpec{spec: j, lastModified: time.Now()}, computeETag(j)) + }, caches) } func (o *OpenAPIService) getSingleGroupBytes(getType string, group string) ([]byte, string, time.Time, error) { - o.rwMutex.RLock() - defer o.rwMutex.RUnlock() + o.mutex.Lock() + defer o.mutex.Unlock() v, ok := o.v3Schema[group] if !ok { return nil, "", time.Now(), fmt.Errorf("Cannot find CRD group %s", group) } - if getType == subTypeJSON { - specBytes, err := v.jsonCache.Get() - if err != nil { - return nil, "", v.lastModified, err - } - etagBytes, err := v.etagCache.Get() - return specBytes, string(etagBytes), v.lastModified, err - } else if getType == subTypeProtobuf { - specPb, err := v.pbCache.Get() - if err != nil { - return nil, "", v.lastModified, err - } - etagBytes, err := v.etagCache.Get() - return specPb, string(etagBytes), v.lastModified, err + result := cached.Result[timedSpec]{} + switch getType { + case subTypeJSON: + result = v.jsonCache.Get() + case subTypeProtobuf, subTypeProtobufDeprecated: + result = v.pbCache.Get() + default: + return nil, "", time.Now(), fmt.Errorf("Invalid accept clause %s", getType) } - return nil, "", time.Now(), fmt.Errorf("Invalid accept clause %s", getType) + return result.Data.spec, result.Etag, result.Data.lastModified, result.Err } -func (o *OpenAPIService) UpdateGroupVersion(group string, openapi *spec3.OpenAPI) (err error) { - o.rwMutex.Lock() - defer o.rwMutex.Unlock() - +// UpdateGroupVersionLazy adds or updates an existing group with the new cached. +func (o *OpenAPIService) UpdateGroupVersionLazy(group string, openapi cached.Data[*spec3.OpenAPI]) { + o.mutex.Lock() + defer o.mutex.Unlock() if _, ok := o.v3Schema[group]; !ok { - o.v3Schema[group] = &OpenAPIV3Group{} + o.v3Schema[group] = newOpenAPIV3Group() + // Since there is a new item, we need to re-build the cache map. + o.discoveryCache.Replace(o.buildDiscoveryCacheLocked()) } - return o.v3Schema[group].UpdateSpec(openapi) + o.v3Schema[group].UpdateSpec(openapi) } -func (o *OpenAPIService) DeleteGroupVersion(group string) { - o.rwMutex.Lock() - defer o.rwMutex.Unlock() - delete(o.v3Schema, group) +func (o *OpenAPIService) UpdateGroupVersion(group string, openapi *spec3.OpenAPI) { + o.UpdateGroupVersionLazy(group, cached.NewResultOK(openapi, uuid.New().String())) } -func ToV3ProtoBinary(json []byte) ([]byte, error) { - document, err := openapi_v3.ParseDocument(json) - if err != nil { - return nil, err - } - return proto.Marshal(document) +func (o *OpenAPIService) DeleteGroupVersion(group string) { + o.mutex.Lock() + defer o.mutex.Unlock() + delete(o.v3Schema, group) + // Rebuild the merge cache map since the items have changed. + o.discoveryCache.Replace(o.buildDiscoveryCacheLocked()) } func (o *OpenAPIService) HandleDiscovery(w http.ResponseWriter, r *http.Request) { - data, _ := o.getGroupBytes() - http.ServeContent(w, r, "/openapi/v3", time.Now(), bytes.NewReader(data)) + result := o.discoveryCache.Get() + if result.Err != nil { + klog.Errorf("Error serving discovery: %s", result.Err) + w.WriteHeader(http.StatusInternalServerError) + return + } + w.Header().Set("Etag", strconv.Quote(result.Etag)) + w.Header().Set("Content-Type", "application/json") + http.ServeContent(w, r, "/openapi/v3", result.Data.lastModified, bytes.NewReader(result.Data.spec)) } func (o *OpenAPIService) HandleGroupVersion(w http.ResponseWriter, r *http.Request) { @@ -210,11 +235,13 @@ func (o *OpenAPIService) HandleGroupVersion(w http.ResponseWriter, r *http.Reque } accepted := []struct { - Type string - SubType string + Type string + SubType string + ReturnedContentType string }{ - {"application", subTypeJSON}, - {"application", subTypeProtobuf}, + {"application", subTypeJSON, "application/" + subTypeJSON}, + {"application", subTypeProtobuf, "application/" + subTypeProtobuf}, + {"application", subTypeProtobufDeprecated, "application/" + subTypeProtobuf}, } for _, clause := range clauses { @@ -229,6 +256,9 @@ func (o *OpenAPIService) HandleGroupVersion(w http.ResponseWriter, r *http.Reque if err != nil { return } + // Set Content-Type header in the reponse + w.Header().Set("Content-Type", accepts.ReturnedContentType) + // ETag must be enclosed in double quotes: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag w.Header().Set("Etag", strconv.Quote(etag)) @@ -262,30 +292,3 @@ func (o *OpenAPIService) RegisterOpenAPIV3VersionedService(servePath string, han handler.HandlePrefix(servePath+"/", http.HandlerFunc(o.HandleGroupVersion)) return nil } - -func (o *OpenAPIV3Group) UpdateSpec(openapi *spec3.OpenAPI) (err error) { - o.rwMutex.Lock() - defer o.rwMutex.Unlock() - - o.jsonCache = o.jsonCache.New(func() ([]byte, error) { - return json.Marshal(openapi) - }) - o.pbCache = o.pbCache.New(func() ([]byte, error) { - json, err := o.jsonCache.Get() - if err != nil { - return nil, err - } - return ToV3ProtoBinary(json) - }) - // TODO: This forces a json marshal of corresponding group-versions. - // We should look to replace this with a faster hashing mechanism. - o.etagCache = o.etagCache.New(func() ([]byte, error) { - json, err := o.jsonCache.Get() - if err != nil { - return nil, err - } - return []byte(computeETag(json)), nil - }) - o.lastModified = time.Now() - return nil -} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/flags.go b/vendor/k8s.io/kube-openapi/pkg/internal/flags.go index 3ff3c8d894..bef6037823 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/flags.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/flags.go @@ -18,3 +18,7 @@ package internal // Used by tests to selectively disable experimental JSON unmarshaler var UseOptimizedJSONUnmarshaling bool = true +var UseOptimizedJSONUnmarshalingV3 bool = true + +// Used by tests to selectively disable experimental JSON marshaler +var UseOptimizedJSONMarshaling bool = true diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/handler/handler_cache.go b/vendor/k8s.io/kube-openapi/pkg/internal/handler/handler_cache.go deleted file mode 100644 index e128c26ebe..0000000000 --- a/vendor/k8s.io/kube-openapi/pkg/internal/handler/handler_cache.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2021 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 handler - -import ( - "sync" -) - -// HandlerCache represents a lazy cache for generating a byte array -// It is used to lazily marshal OpenAPI v2/v3 and lazily generate the ETag -type HandlerCache struct { - BuildCache func() ([]byte, error) - once sync.Once - bytes []byte - err error -} - -// Get either returns the cached value or calls BuildCache() once before caching and returning -// its results. If BuildCache returns an error, the last valid value for the cache (from prior -// calls to New()) is used instead if possible. -func (c *HandlerCache) Get() ([]byte, error) { - c.once.Do(func() { - bytes, err := c.BuildCache() - // if there is an error updating the cache, there can be situations where - // c.bytes contains a valid value (carried over from the previous update) - // but c.err is also not nil; the cache user is expected to check for this - c.err = err - if c.err == nil { - // don't override previous spec if we had an error - c.bytes = bytes - } - }) - return c.bytes, c.err -} - -// New creates a new HandlerCache for situations where a cache refresh is needed. -// This function is not thread-safe and should not be called at the same time as Get(). -func (c *HandlerCache) New(cacheBuilder func() ([]byte, error)) HandlerCache { - return HandlerCache{ - bytes: c.bytes, - BuildCache: cacheBuilder, - } -} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/serialization.go b/vendor/k8s.io/kube-openapi/pkg/internal/serialization.go new file mode 100644 index 0000000000..7393bacf70 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/serialization.go @@ -0,0 +1,65 @@ +/* +Copyright 2023 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 internal + +import ( + "github.com/go-openapi/jsonreference" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" +) + +// DeterministicMarshal calls the jsonv2 library with the deterministic +// flag in order to have stable marshaling. +func DeterministicMarshal(in any) ([]byte, error) { + return jsonv2.MarshalOptions{Deterministic: true}.Marshal(jsonv2.EncodeOptions{}, in) +} + +// JSONRefFromMap populates a json reference object if the map v contains a $ref key. +func JSONRefFromMap(jsonRef *jsonreference.Ref, v map[string]interface{}) error { + if v == nil { + return nil + } + if vv, ok := v["$ref"]; ok { + if str, ok := vv.(string); ok { + ref, err := jsonreference.New(str) + if err != nil { + return err + } + *jsonRef = ref + } + } + return nil +} + +// SanitizeExtensions sanitizes the input map such that non extension +// keys (non x-*, X-*) keys are dropped from the map. Returns the new +// modified map, or nil if the map is now empty. +func SanitizeExtensions(e map[string]interface{}) map[string]interface{} { + for k := range e { + if !IsExtensionKey(k) { + delete(e, k) + } + } + if len(e) == 0 { + e = nil + } + return e +} + +// IsExtensionKey returns true if the input string is of format x-* or X-* +func IsExtensionKey(k string) bool { + return len(k) > 1 && (k[0] == 'x' || k[0] == 'X') && k[1] == '-' +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go index febde20f9c..e6c6216ff3 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go @@ -34,6 +34,13 @@ type MarshalOptions struct { // unknown JSON object members. DiscardUnknownMembers bool + // Deterministic specifies that the same input value will be serialized + // as the exact same output bytes. Different processes of + // the same program will serialize equal values to the same bytes, + // but different versions of the same program are not guaranteed + // to produce the exact same sequence of bytes. + Deterministic bool + // formatDepth is the depth at which we respect the format flag. formatDepth int // format is custom formatting for the value at the specified depth. diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go index 204d0648dd..c62b1f3203 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go @@ -62,7 +62,7 @@ func unmarshalValueAny(uo UnmarshalOptions, dec *Decoder) (any, error) { } return dec.stringCache.make(val), nil case '0': - fv, _ := parseFloat(val, 64) // ignore error since readValue gaurantees val is valid + fv, _ := parseFloat(val, 64) // ignore error since readValue guarantees val is valid return fv, nil default: panic("BUG: invalid kind: " + k.String()) @@ -99,13 +99,32 @@ func marshalObjectAny(mo MarshalOptions, enc *Encoder, obj map[string]any) error if !enc.options.AllowInvalidUTF8 { enc.tokens.last.disableNamespace() } - for name, val := range obj { - if err := enc.WriteToken(String(name)); err != nil { - return err + if !mo.Deterministic || len(obj) <= 1 { + for name, val := range obj { + if err := enc.WriteToken(String(name)); err != nil { + return err + } + if err := marshalValueAny(mo, enc, val); err != nil { + return err + } } - if err := marshalValueAny(mo, enc, val); err != nil { - return err + } else { + names := getStrings(len(obj)) + var i int + for name := range obj { + (*names)[i] = name + i++ + } + names.Sort() + for _, name := range *names { + if err := enc.WriteToken(String(name)); err != nil { + return err + } + if err := marshalValueAny(mo, enc, obj[name]); err != nil { + return err + } } + putStrings(names) } if err := enc.WriteToken(ObjectEnd); err != nil { return err diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go index fcf3d50000..fd26eba352 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go @@ -5,6 +5,7 @@ package json import ( + "bytes" "encoding/base32" "encoding/base64" "encoding/hex" @@ -12,6 +13,7 @@ import ( "fmt" "math" "reflect" + "sort" "strconv" "sync" ) @@ -228,13 +230,7 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler { } } val := enc.UnusedBuffer() - var b []byte - if va.Kind() == reflect.Array { - // TODO(https://go.dev/issue/47066): Avoid reflect.Value.Slice. - b = va.Slice(0, va.Len()).Bytes() - } else { - b = va.Bytes() - } + b := va.Bytes() n := len(`"`) + encodedLen(len(b)) + len(`"`) if cap(val) < n { val = make([]byte, n) @@ -248,19 +244,19 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler { } unmarshalDefault := fncs.unmarshal fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - decode, decodedLen := decodeBase64, decodedLenBase64 + decode, decodedLen, encodedLen := decodeBase64, decodedLenBase64, encodedLenBase64 if uo.format != "" && uo.formatDepth == dec.tokens.depth() { switch uo.format { case "base64": - decode, decodedLen = decodeBase64, decodedLenBase64 + decode, decodedLen, encodedLen = decodeBase64, decodedLenBase64, encodedLenBase64 case "base64url": - decode, decodedLen = decodeBase64URL, decodedLenBase64URL + decode, decodedLen, encodedLen = decodeBase64URL, decodedLenBase64URL, encodedLenBase64URL case "base32": - decode, decodedLen = decodeBase32, decodedLenBase32 + decode, decodedLen, encodedLen = decodeBase32, decodedLenBase32, encodedLenBase32 case "base32hex": - decode, decodedLen = decodeBase32Hex, decodedLenBase32Hex + decode, decodedLen, encodedLen = decodeBase32Hex, decodedLenBase32Hex, encodedLenBase32Hex case "base16", "hex": - decode, decodedLen = decodeBase16, decodedLenBase16 + decode, decodedLen, encodedLen = decodeBase16, decodedLenBase16, encodedLenBase16 case "array": uo.format = "" return unmarshalDefault(uo, dec, va) @@ -290,23 +286,28 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler { n-- } n = decodedLen(n) - var b []byte + b := va.Bytes() if va.Kind() == reflect.Array { - // TODO(https://go.dev/issue/47066): Avoid reflect.Value.Slice. - b = va.Slice(0, va.Len()).Bytes() if n != len(b) { err := fmt.Errorf("decoded base64 length of %d mismatches array length of %d", n, len(b)) return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} } } else { - b = va.Bytes() if b == nil || cap(b) < n { b = make([]byte, n) } else { b = b[:n] } } - if _, err := decode(b, val); err != nil { + n2, err := decode(b, val) + if err == nil && len(val) != encodedLen(n2) { + // TODO(https://go.dev/issue/53845): RFC 4648, section 3.3, + // specifies that non-alphabet characters must be rejected. + // Unfortunately, the "base32" and "base64" packages allow + // '\r' and '\n' characters by default. + err = errors.New("illegal data at input byte " + strconv.Itoa(bytes.IndexAny(val, "\r\n"))) + } + if err != nil { return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} } if va.Kind() == reflect.Slice { @@ -412,7 +413,7 @@ func makeUintArshaler(t reflect.Type) *arshaler { return nil } - x := math.Float64frombits(uint64(va.Uint())) + x := math.Float64frombits(va.Uint()) return enc.writeNumber(x, rawUintNumber, mo.StringifyNumbers) } fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { @@ -450,7 +451,7 @@ func makeUintArshaler(t reflect.Type) *arshaler { err := fmt.Errorf("cannot parse %q as unsigned integer: %w", val, strconv.ErrRange) return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} } - va.SetUint(uint64(n)) + va.SetUint(n) return nil } return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} @@ -549,23 +550,9 @@ func makeFloatArshaler(t reflect.Type) *arshaler { return &fncs } -var mapIterPool = sync.Pool{ - New: func() any { return new(reflect.MapIter) }, -} - -func getMapIter(mv reflect.Value) *reflect.MapIter { - iter := mapIterPool.Get().(*reflect.MapIter) - iter.Reset(mv) - return iter -} -func putMapIter(iter *reflect.MapIter) { - iter.Reset(reflect.Value{}) // allow underlying map to be garbage collected - mapIterPool.Put(iter) -} - func makeMapArshaler(t reflect.Type) *arshaler { // NOTE: The logic below disables namespaces for tracking duplicate names - // when handling map keys with a unique represention. + // when handling map keys with a unique representation. // NOTE: Values retrieved from a map are not addressable, // so we shallow copy the values to make them addressable and @@ -641,24 +628,76 @@ func makeMapArshaler(t reflect.Type) *arshaler { enc.tokens.last.disableNamespace() } - // NOTE: Map entries are serialized in a non-deterministic order. - // Users that need stable output should call RawValue.Canonicalize. - // TODO(go1.19): Remove use of a sync.Pool with reflect.MapIter. - // Calling reflect.Value.MapRange no longer allocates. - // See https://go.dev/cl/400675. - iter := getMapIter(va.Value) - defer putMapIter(iter) - for iter.Next() { - k.SetIterKey(iter) - if err := marshalKey(mko, enc, k); err != nil { - // TODO: If err is errMissingName, then wrap it as a - // SemanticError since this key type cannot be serialized - // as a JSON string. - return err + switch { + case !mo.Deterministic || n <= 1: + for iter := va.Value.MapRange(); iter.Next(); { + k.SetIterKey(iter) + if err := marshalKey(mko, enc, k); err != nil { + // TODO: If err is errMissingName, then wrap it as a + // SemanticError since this key type cannot be serialized + // as a JSON string. + return err + } + v.SetIterValue(iter) + if err := marshalVal(mo, enc, v); err != nil { + return err + } } - v.SetIterValue(iter) - if err := marshalVal(mo, enc, v); err != nil { - return err + case !nonDefaultKey && t.Key().Kind() == reflect.String: + names := getStrings(n) + for i, iter := 0, va.Value.MapRange(); i < n && iter.Next(); i++ { + k.SetIterKey(iter) + (*names)[i] = k.String() + } + names.Sort() + for _, name := range *names { + if err := enc.WriteToken(String(name)); err != nil { + return err + } + // TODO(https://go.dev/issue/57061): Use v.SetMapIndexOf. + k.SetString(name) + v.Set(va.MapIndex(k.Value)) + if err := marshalVal(mo, enc, v); err != nil { + return err + } + } + putStrings(names) + default: + type member struct { + name string // unquoted name + key addressableValue + } + members := make([]member, n) + keys := reflect.MakeSlice(reflect.SliceOf(t.Key()), n, n) + for i, iter := 0, va.Value.MapRange(); i < n && iter.Next(); i++ { + // Marshal the member name. + k := addressableValue{keys.Index(i)} // indexed slice element is always addressable + k.SetIterKey(iter) + if err := marshalKey(mko, enc, k); err != nil { + // TODO: If err is errMissingName, then wrap it as a + // SemanticError since this key type cannot be serialized + // as a JSON string. + return err + } + name := enc.unwriteOnlyObjectMemberName() + members[i] = member{name, k} + } + // TODO: If AllowDuplicateNames is enabled, then sort according + // to reflect.Value as well if the names are equal. + // See internal/fmtsort. + // TODO(https://go.dev/issue/47619): Use slices.SortFunc instead. + sort.Slice(members, func(i, j int) bool { + return lessUTF16(members[i].name, members[j].name) + }) + for _, member := range members { + if err := enc.WriteToken(String(member.name)); err != nil { + return err + } + // TODO(https://go.dev/issue/57061): Use v.SetMapIndexOf. + v.Set(va.MapIndex(member.key.Value)) + if err := marshalVal(mo, enc, v); err != nil { + return err + } } } } @@ -856,7 +895,7 @@ func makeStructArshaler(t reflect.Type) *arshaler { // 2. The object namespace is guaranteed to be disabled. // 3. The object name is guaranteed to be valid and pre-escaped. // 4. There is no need to flush the buffer (for unwrite purposes). - // 5. There is no possibility of an error occuring. + // 5. There is no possibility of an error occurring. if optimizeCommon { // Append any delimiters or optional whitespace. if enc.tokens.last.length() > 0 { @@ -996,7 +1035,7 @@ func makeStructArshaler(t reflect.Type) *arshaler { if fields.inlinedFallback == nil { // Skip unknown value since we have no place to store it. - if err := dec.skipValue(); err != nil { + if err := dec.SkipValue(); err != nil { return err } } else { diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go index 7476eda301..258a98247d 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go @@ -5,6 +5,7 @@ package json import ( + "bytes" "errors" "reflect" ) @@ -89,35 +90,61 @@ func marshalInlinedFallbackAll(mo MarshalOptions, enc *Encoder, va addressableVa } return nil } else { - if v.Len() == 0 { + m := v // must be a map[string]V + n := m.Len() + if n == 0 { return nil } - m := v + mk := newAddressableValue(stringType) mv := newAddressableValue(m.Type().Elem()) - for iter := m.MapRange(); iter.Next(); { - b, err := appendString(enc.UnusedBuffer(), iter.Key().String(), !enc.options.AllowInvalidUTF8, nil) + marshalKey := func(mk addressableValue) error { + b, err := appendString(enc.UnusedBuffer(), mk.String(), !enc.options.AllowInvalidUTF8, nil) if err != nil { return err } if insertUnquotedName != nil { - isVerbatim := consumeSimpleString(b) == len(b) + isVerbatim := bytes.IndexByte(b, '\\') < 0 name := unescapeStringMayCopy(b, isVerbatim) if !insertUnquotedName(name) { return &SyntacticError{str: "duplicate name " + string(b) + " in object"} } } - if err := enc.WriteValue(b); err != nil { - return err + return enc.WriteValue(b) + } + marshalVal := f.fncs.marshal + if mo.Marshalers != nil { + marshalVal, _ = mo.Marshalers.lookup(marshalVal, mv.Type()) + } + if !mo.Deterministic || n <= 1 { + for iter := m.MapRange(); iter.Next(); { + mk.SetIterKey(iter) + if err := marshalKey(mk); err != nil { + return err + } + mv.Set(iter.Value()) + if err := marshalVal(mo, enc, mv); err != nil { + return err + } } - - mv.Set(iter.Value()) - marshal := f.fncs.marshal - if mo.Marshalers != nil { - marshal, _ = mo.Marshalers.lookup(marshal, mv.Type()) + } else { + names := getStrings(n) + for i, iter := 0, m.Value.MapRange(); i < n && iter.Next(); i++ { + mk.SetIterKey(iter) + (*names)[i] = mk.String() } - if err := marshal(mo, enc, mv); err != nil { - return err + names.Sort() + for _, name := range *names { + mk.SetString(name) + if err := marshalKey(mk); err != nil { + return err + } + // TODO(https://go.dev/issue/57061): Use mv.SetMapIndexOf. + mv.Set(m.MapIndex(mk.Value)) + if err := marshalVal(mo, enc, mv); err != nil { + return err + } } + putStrings(names) } return nil } @@ -162,7 +189,7 @@ func unmarshalInlinedFallbackNext(uo UnmarshalOptions, dec *Decoder, va addressa } else { name := string(unquotedName) // TODO: Intern this? - m := v + m := v // must be a map[string]V if m.IsNil() { m.Set(reflect.MakeMap(m.Type())) } diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go index ef4e1f5e3d..20899c868c 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go @@ -21,8 +21,8 @@ var ( ) // MarshalerV1 is implemented by types that can marshal themselves. -// It is recommended that types implement MarshalerV2 unless -// the implementation is trying to avoid a hard dependency on this package. +// It is recommended that types implement MarshalerV2 unless the implementation +// is trying to avoid a hard dependency on the "jsontext" package. // // It is recommended that implementations return a buffer that is safe // for the caller to retain and potentially mutate. diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go index 22e802221e..fc8d5b0070 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go @@ -5,6 +5,7 @@ package json import ( + "errors" "fmt" "reflect" "strings" @@ -85,25 +86,39 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler { fncs.nonDefault = true fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { format := time.RFC3339Nano + isRFC3339 := true if mo.format != "" && mo.formatDepth == enc.tokens.depth() { var err error - format, err = checkTimeFormat(mo.format) + format, isRFC3339, err = checkTimeFormat(mo.format) if err != nil { return &SemanticError{action: "marshal", GoType: t, Err: err} } } tt := va.Interface().(time.Time) - if y := tt.Year(); y < 0 || y >= 10000 { - // RFC 3339 is clear that years are 4 digits exactly. - // See https://go.dev/issue/4556#c15 for more discussion. - err := fmt.Errorf("year %d outside of range [0,9999]", y) - return &SemanticError{action: "marshal", GoType: t, Err: err} - } b := enc.UnusedBuffer() b = append(b, '"') b = tt.AppendFormat(b, format) b = append(b, '"') + if isRFC3339 { + // Not all Go timestamps can be represented as valid RFC 3339. + // Explicitly check for these edge cases. + // See https://go.dev/issue/4556 and https://go.dev/issue/54580. + var err error + switch b := b[len(`"`) : len(b)-len(`"`)]; { + case b[len("9999")] != '-': // year must be exactly 4 digits wide + err = errors.New("year outside of range [0,9999]") + case b[len(b)-1] != 'Z': + c := b[len(b)-len("Z07:00")] + if ('0' <= c && c <= '9') || parseDec2(b[len(b)-len("07:00"):]) >= 24 { + err = errors.New("timezone hour outside of range [0,23]") + } + } + if err != nil { + return &SemanticError{action: "marshal", GoType: t, Err: err} + } + return enc.WriteValue(b) // RFC 3339 never needs JSON escaping + } // The format may contain special characters that need escaping. // Verify that the result is a valid JSON string (common case), // otherwise escape the string correctly (slower case). @@ -113,10 +128,11 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler { return enc.WriteValue(b) } fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - format := time.RFC3339Nano + format := time.RFC3339 + isRFC3339 := true if uo.format != "" && uo.formatDepth == dec.tokens.depth() { var err error - format, err = checkTimeFormat(uo.format) + format, isRFC3339, err = checkTimeFormat(uo.format) if err != nil { return &SemanticError{action: "unmarshal", GoType: t, Err: err} } @@ -136,6 +152,29 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler { case '"': val = unescapeStringMayCopy(val, flags.isVerbatim()) tt2, err := time.Parse(format, string(val)) + if isRFC3339 && err == nil { + // TODO(https://go.dev/issue/54580): RFC 3339 specifies + // the exact grammar of a valid timestamp. However, + // the parsing functionality in "time" is too loose and + // incorrectly accepts invalid timestamps as valid. + // Remove these manual checks when "time" checks it for us. + newParseError := func(layout, value, layoutElem, valueElem, message string) error { + return &time.ParseError{Layout: layout, Value: value, LayoutElem: layoutElem, ValueElem: valueElem, Message: message} + } + switch { + case val[len("2006-01-02T")+1] == ':': // hour must be two digits + err = newParseError(format, string(val), "15", string(val[len("2006-01-02T"):][:1]), "") + case val[len("2006-01-02T15:04:05")] == ',': // sub-second separator must be a period + err = newParseError(format, string(val), ".", ",", "") + case val[len(val)-1] != 'Z': + switch { + case parseDec2(val[len(val)-len("07:00"):]) >= 24: // timezone hour must be in range + err = newParseError(format, string(val), "Z07:00", string(val[len(val)-len("Z07:00"):]), ": timezone hour out of range") + case parseDec2(val[len(val)-len("00"):]) >= 60: // timezone minute must be in range + err = newParseError(format, string(val), "Z07:00", string(val[len(val)-len("Z07:00"):]), ": timezone minute out of range") + } + } + } if err != nil { return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} } @@ -149,48 +188,54 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler { return fncs } -func checkTimeFormat(format string) (string, error) { +func checkTimeFormat(format string) (string, bool, error) { // We assume that an exported constant in the time package will // always start with an uppercase ASCII letter. if len(format) > 0 && 'A' <= format[0] && format[0] <= 'Z' { switch format { case "ANSIC": - return time.ANSIC, nil + return time.ANSIC, false, nil case "UnixDate": - return time.UnixDate, nil + return time.UnixDate, false, nil case "RubyDate": - return time.RubyDate, nil + return time.RubyDate, false, nil case "RFC822": - return time.RFC822, nil + return time.RFC822, false, nil case "RFC822Z": - return time.RFC822Z, nil + return time.RFC822Z, false, nil case "RFC850": - return time.RFC850, nil + return time.RFC850, false, nil case "RFC1123": - return time.RFC1123, nil + return time.RFC1123, false, nil case "RFC1123Z": - return time.RFC1123Z, nil + return time.RFC1123Z, false, nil case "RFC3339": - return time.RFC3339, nil + return time.RFC3339, true, nil case "RFC3339Nano": - return time.RFC3339Nano, nil + return time.RFC3339Nano, true, nil case "Kitchen": - return time.Kitchen, nil + return time.Kitchen, false, nil case "Stamp": - return time.Stamp, nil + return time.Stamp, false, nil case "StampMilli": - return time.StampMilli, nil + return time.StampMilli, false, nil case "StampMicro": - return time.StampMicro, nil + return time.StampMicro, false, nil case "StampNano": - return time.StampNano, nil + return time.StampNano, false, nil default: // Reject any format that is an exported Go identifier in case // new format constants are added to the time package. if strings.TrimFunc(format, isLetterOrDigit) == "" { - return "", fmt.Errorf("undefined format layout: %v", format) + return "", false, fmt.Errorf("undefined format layout: %v", format) } } } - return format, nil + return format, false, nil +} + +// parseDec2 parses b as an unsigned, base-10, 2-digit number. +// It panics if len(b) < 2. The result is undefined if digits are not base-10. +func parseDec2(b []byte) byte { + return 10*(b[0]-'0') + (b[1] - '0') } diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go index 998ad68fc0..0d68b32338 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go @@ -347,9 +347,9 @@ func (d *Decoder) PeekKind() Kind { return next } -// skipValue is semantically equivalent to calling ReadValue and discarding +// SkipValue is semantically equivalent to calling ReadValue and discarding // the result except that memory is not wasted trying to hold the entire result. -func (d *Decoder) skipValue() error { +func (d *Decoder) SkipValue() error { switch d.PeekKind() { case '{', '[': // For JSON objects and arrays, keep skipping all tokens @@ -374,7 +374,7 @@ func (d *Decoder) skipValue() error { } // ReadToken reads the next Token, advancing the read offset. -// The returned token is only valid until the next Peek or Read call. +// The returned token is only valid until the next Peek, Read, or Skip call. // It returns io.EOF if there are no more tokens. func (d *Decoder) ReadToken() (Token, error) { // Determine the next kind. @@ -585,7 +585,7 @@ func (f valueFlags) isCanonical() bool { return f&stringNonCanonical == 0 } // ReadValue returns the next raw JSON value, advancing the read offset. // The value is stripped of any leading or trailing whitespace. -// The returned value is only valid until the next Peek or Read call and +// The returned value is only valid until the next Peek, Read, or Skip call and // may not be mutated while the Decoder remains in use. // If the decoder is currently at the end token for an object or array, // then it reports a SyntacticError and the internal state remains unchanged. @@ -1013,7 +1013,7 @@ func (d *Decoder) InputOffset() int64 { // UnreadBuffer returns the data remaining in the unread buffer, // which may contain zero or more bytes. // The returned buffer must not be mutated while Decoder continues to be used. -// The buffer contents are valid until the next Peek or Read call. +// The buffer contents are valid until the next Peek, Read, or Skip call. func (d *Decoder) UnreadBuffer() []byte { return d.unreadBuffer() } @@ -1213,7 +1213,7 @@ func consumeStringResumable(flags *valueFlags, b []byte, resumeOffset int, valid return n, &SyntacticError{str: "invalid escape sequence " + strconv.Quote(string(b[n:n+6])) + " within string"} } // Only certain control characters can use the \uFFFF notation - // for canonical formating (per RFC 8785, section 3.2.2.2.). + // for canonical formatting (per RFC 8785, section 3.2.2.2.). switch v1 { // \uFFFF notation not permitted for these characters. case '\b', '\f', '\n', '\r', '\t': diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go index ba4af4b7b1..e4eefa3de9 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go @@ -8,8 +8,7 @@ // primitive data types such as booleans, strings, and numbers, // in addition to structured data types such as objects and arrays. // -// -// Terminology +// # Terminology // // This package uses the terms "encode" and "decode" for syntactic functionality // that is concerned with processing JSON based on its grammar, and @@ -32,8 +31,7 @@ // // See RFC 8259 for more information. // -// -// Specifications +// # Specifications // // Relevant specifications include RFC 4627, RFC 7159, RFC 7493, RFC 8259, // and RFC 8785. Each RFC is generally a stricter subset of another RFC. @@ -60,8 +58,7 @@ // In particular, it makes specific choices about behavior that RFC 8259 // leaves as undefined in order to ensure greater interoperability. // -// -// JSON Representation of Go structs +// # JSON Representation of Go structs // // A Go struct is naturally represented as a JSON object, // where each Go struct field corresponds with a JSON object member. diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go index 5f98a8409e..5b81ca15af 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go @@ -347,6 +347,30 @@ func (e *Encoder) unwriteEmptyObjectMember(prevName *string) bool { return true } +// unwriteOnlyObjectMemberName unwrites the only object member name +// and returns the unquoted name. +func (e *Encoder) unwriteOnlyObjectMemberName() string { + if last := e.tokens.last; !last.isObject() || last.length() != 1 { + panic("BUG: must be called on an object after writing first name") + } + + // Unwrite the name and whitespace. + b := trimSuffixString(e.buf) + isVerbatim := bytes.IndexByte(e.buf[len(b):], '\\') < 0 + name := string(unescapeStringMayCopy(e.buf[len(b):], isVerbatim)) + e.buf = trimSuffixWhitespace(b) + + // Undo state changes. + e.tokens.last.decrement() + if !e.options.AllowDuplicateNames { + if e.tokens.last.isActiveNamespace() { + e.namespaces.last().removeLast() + } + e.names.clearLast() + } + return name +} + func trimSuffixWhitespace(b []byte) []byte { // NOTE: The arguments and logic are kept simple to keep this inlineable. n := len(b) - 1 diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go index f722822117..60e93270fb 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go @@ -8,6 +8,7 @@ import ( "bytes" "io" "math/bits" + "sort" "sync" ) @@ -148,3 +149,34 @@ func putStreamingDecoder(d *Decoder) { streamingDecoderPool.Put(d) } } + +var stringsPools = &sync.Pool{New: func() any { return new(stringSlice) }} + +type stringSlice []string + +// getStrings returns a non-nil pointer to a slice with length n. +func getStrings(n int) *stringSlice { + s := stringsPools.Get().(*stringSlice) + if cap(*s) < n { + *s = make([]string, n) + } + *s = (*s)[:n] + return s +} + +func putStrings(s *stringSlice) { + if cap(*s) > 1<<10 { + *s = nil // avoid pinning arbitrarily large amounts of memory + } + stringsPools.Put(s) +} + +// Sort sorts the string slice according to RFC 8785, section 3.2.3. +func (ss *stringSlice) Sort() { + // TODO(https://go.dev/issue/47619): Use slices.SortFunc instead. + sort.Sort(ss) +} + +func (ss *stringSlice) Len() int { return len(*ss) } +func (ss *stringSlice) Less(i, j int) bool { return lessUTF16((*ss)[i], (*ss)[j]) } +func (ss *stringSlice) Swap(i, j int) { (*ss)[i], (*ss)[j] = (*ss)[j], (*ss)[i] } diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go index d9c33f2b4b..ee14c753fe 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go @@ -721,7 +721,7 @@ func (s *uintSet) has(i uint) bool { return s.lo.has(i) } else { i -= 64 - iHi, iLo := int(i/64), uint(i%64) + iHi, iLo := int(i/64), i%64 return iHi < len(s.hi) && s.hi[iHi].has(iLo) } } @@ -735,7 +735,7 @@ func (s *uintSet) insert(i uint) bool { return !has } else { i -= 64 - iHi, iLo := int(i/64), uint(i%64) + iHi, iLo := int(i/64), i%64 if iHi >= len(s.hi) { s.hi = append(s.hi, make([]uintSet64, iHi+1-len(s.hi))...) s.hi = s.hi[:cap(s.hi)] diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go index 08509c296b..9acba7dadf 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go @@ -112,7 +112,7 @@ func Bool(b bool) Token { return False } -// String construct a Token representing a JSON string. +// String constructs a Token representing a JSON string. // The provided string should contain valid UTF-8, otherwise invalid characters // may be mangled as the Unicode replacement character. func String(s string) Token { @@ -225,7 +225,7 @@ func (t Token) appendString(dst []byte, validateUTF8, preserveRaw bool, escapeRu } // String returns the unescaped string value for a JSON string. -// For other JSON kinds, this returns the raw JSON represention. +// For other JSON kinds, this returns the raw JSON representation. func (t Token) String() string { // This is inlinable to take advantage of "function outlining". // This avoids an allocation for the string(b) conversion @@ -373,10 +373,10 @@ func (t Token) Int() int64 { case 'i': return int64(t.num) case 'u': - if uint64(t.num) > maxInt64 { + if t.num > maxInt64 { return maxInt64 } - return int64(uint64(t.num)) + return int64(t.num) } } @@ -425,7 +425,7 @@ func (t Token) Uint() uint64 { // Handle exact integer value. switch t.str[0] { case 'u': - return uint64(t.num) + return t.num case 'i': if int64(t.num) < minUint64 { return minUint64 diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go index fe88e4fb5e..e0bd1b31d7 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go @@ -263,7 +263,7 @@ func reorderObjects(d *Decoder, scratch *[]byte) { afterValue := d.InputOffset() if isSorted && len(*members) > 0 { - isSorted = lessUTF16(prevName, name) + isSorted = lessUTF16(prevName, []byte(name)) } *members = append(*members, memberName{name, beforeName, afterValue}) prevName = name @@ -317,7 +317,7 @@ func reorderObjects(d *Decoder, scratch *[]byte) { // to the UTF-16 codepoints of the UTF-8 encoded input strings. // This implements the ordering specified in RFC 8785, section 3.2.3. // The inputs must be valid UTF-8, otherwise this may panic. -func lessUTF16(x, y []byte) bool { +func lessUTF16[Bytes []byte | string](x, y Bytes) bool { // NOTE: This is an optimized, allocation-free implementation // of lessUTF16Simple in fuzz_test.go. FuzzLessUTF16 verifies that the // two implementations agree on the result of comparing any two strings. @@ -326,8 +326,13 @@ func lessUTF16(x, y []byte) bool { return ('\u0000' <= r && r <= '\uD7FF') || ('\uE000' <= r && r <= '\uFFFF') } + var invalidUTF8 bool + x0, y0 := x, y for { if len(x) == 0 || len(y) == 0 { + if len(x) == len(y) && invalidUTF8 { + return string(x0) < string(y0) + } return len(x) < len(y) } @@ -341,35 +346,36 @@ func lessUTF16(x, y []byte) bool { } // Decode next pair of runes as UTF-8. - rx, nx := utf8.DecodeRune(x) - ry, ny := utf8.DecodeRune(y) - switch { - - // Both runes encode as either a single or surrogate pair - // of UTF-16 codepoints. - case isUTF16Self(rx) == isUTF16Self(ry): - if rx != ry { - return rx < ry - } + // TODO(https://go.dev/issue/56948): Use a generic implementation + // of utf8.DecodeRune, or rely on a compiler optimization to statically + // hide the cost of a type switch (https://go.dev/issue/57072). + var rx, ry rune + var nx, ny int + switch any(x).(type) { + case string: + rx, nx = utf8.DecodeRuneInString(string(x)) + ry, ny = utf8.DecodeRuneInString(string(y)) + case []byte: + rx, nx = utf8.DecodeRune([]byte(x)) + ry, ny = utf8.DecodeRune([]byte(y)) + } + selfx := isUTF16Self(rx) + selfy := isUTF16Self(ry) + switch { // The x rune is a single UTF-16 codepoint, while // the y rune is a surrogate pair of UTF-16 codepoints. - case isUTF16Self(rx): - ry, _ := utf16.EncodeRune(ry) - if rx != ry { - return rx < ry - } - panic("BUG: invalid UTF-8") // implies rx is an unpaired surrogate half - + case selfx && !selfy: + ry, _ = utf16.EncodeRune(ry) // The y rune is a single UTF-16 codepoint, while // the x rune is a surrogate pair of UTF-16 codepoints. - case isUTF16Self(ry): - rx, _ := utf16.EncodeRune(rx) - if rx != ry { - return rx < ry - } - panic("BUG: invalid UTF-8") // implies ry is an unpaired surrogate half + case selfy && !selfx: + rx, _ = utf16.EncodeRune(rx) + } + if rx != ry { + return rx < ry } + invalidUTF8 = invalidUTF8 || (rx == utf8.RuneError && nx == 1) || (ry == utf8.RuneError && ny == 1) x, y = x[nx:], y[ny:] } } diff --git a/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go b/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go new file mode 100644 index 0000000000..61141a500d --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go @@ -0,0 +1,260 @@ +/* +Copyright 2022 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 schemaconv + +import ( + "errors" + "path" + "strings" + + "k8s.io/kube-openapi/pkg/validation/spec" + "sigs.k8s.io/structured-merge-diff/v4/schema" +) + +// ToSchemaFromOpenAPI converts a directory of OpenAPI schemas to an smd Schema. +// - models: a map from definition name to OpenAPI V3 structural schema for each definition. +// Key in map is used to resolve references in the schema. +// - preserveUnknownFields: flag indicating whether unknown fields in all schemas should be preserved. +// - returns: nil and an error if there is a parse error, or if schema does not satisfy a +// required structural schema invariant for conversion. If no error, returns +// a new smd schema. +// +// Schema should be validated as structural before using with this function, or +// there may be information lost. +func ToSchemaFromOpenAPI(models map[string]*spec.Schema, preserveUnknownFields bool) (*schema.Schema, error) { + c := convert{ + preserveUnknownFields: preserveUnknownFields, + output: &schema.Schema{}, + } + + for name, spec := range models { + // Skip/Ignore top-level references + if len(spec.Ref.String()) > 0 { + continue + } + + var a schema.Atom + + // Hard-coded schemas for now as proto_models implementation functions. + // https://github.com/kubernetes/kube-openapi/issues/364 + if name == quantityResource { + a = schema.Atom{ + Scalar: untypedDef.Atom.Scalar, + } + } else if name == rawExtensionResource { + a = untypedDef.Atom + } else { + c2 := c.push(name, &a) + c2.visitSpec(spec) + c.pop(c2) + } + + c.insertTypeDef(name, a) + } + + if len(c.errorMessages) > 0 { + return nil, errors.New(strings.Join(c.errorMessages, "\n")) + } + + c.addCommonTypes() + return c.output, nil +} + +func (c *convert) visitSpec(m *spec.Schema) { + // Check if this schema opts its descendants into preserve-unknown-fields + if p, ok := m.Extensions["x-kubernetes-preserve-unknown-fields"]; ok && p == true { + c.preserveUnknownFields = true + } + a := c.top() + *a = c.parseSchema(m) +} + +func (c *convert) parseSchema(m *spec.Schema) schema.Atom { + // k8s-generated OpenAPI specs have historically used only one value for + // type and starting with OpenAPIV3 it is only allowed to be + // a single string. + typ := "" + if len(m.Type) > 0 { + typ = m.Type[0] + } + + // Structural Schemas produced by kubernetes follow very specific rules which + // we can use to infer the SMD type: + switch typ { + case "": + // According to Swagger docs: + // https://swagger.io/docs/specification/data-models/data-types/#any + // + // If no type is specified, it is equivalent to accepting any type. + return schema.Atom{ + Scalar: ptr(schema.Scalar("untyped")), + List: c.parseList(m), + Map: c.parseObject(m), + } + + case "object": + return schema.Atom{ + Map: c.parseObject(m), + } + case "array": + return schema.Atom{ + List: c.parseList(m), + } + case "integer", "boolean", "number", "string": + return convertPrimitive(typ, m.Format) + default: + c.reportError("unrecognized type: '%v'", typ) + return schema.Atom{ + Scalar: ptr(schema.Scalar("untyped")), + } + } +} + +func (c *convert) makeOpenAPIRef(specSchema *spec.Schema) schema.TypeRef { + refString := specSchema.Ref.String() + + // Special-case handling for $ref stored inside a single-element allOf + if len(refString) == 0 && len(specSchema.AllOf) == 1 && len(specSchema.AllOf[0].Ref.String()) > 0 { + refString = specSchema.AllOf[0].Ref.String() + } + + if _, n := path.Split(refString); len(n) > 0 { + //!TODO: Refactor the field ElementRelationship override + // we can generate the types with overrides ahead of time rather than + // requiring the hacky runtime support + // (could just create a normalized key struct containing all customizations + // to deduplicate) + mapRelationship, err := getMapElementRelationship(specSchema.Extensions) + if err != nil { + c.reportError(err.Error()) + } + + if len(mapRelationship) > 0 { + return schema.TypeRef{ + NamedType: &n, + ElementRelationship: &mapRelationship, + } + } + + return schema.TypeRef{ + NamedType: &n, + } + + } + var inlined schema.Atom + + // compute the type inline + c2 := c.push("inlined in "+c.currentName, &inlined) + c2.preserveUnknownFields = c.preserveUnknownFields + c2.visitSpec(specSchema) + c.pop(c2) + + return schema.TypeRef{ + Inlined: inlined, + } +} + +func (c *convert) parseObject(s *spec.Schema) *schema.Map { + var fields []schema.StructField + for name, member := range s.Properties { + fields = append(fields, schema.StructField{ + Name: name, + Type: c.makeOpenAPIRef(&member), + Default: member.Default, + }) + } + + // AdditionalProperties informs the schema of any "unknown" keys + // Unknown keys are enforced by the ElementType field. + elementType := func() schema.TypeRef { + if s.AdditionalProperties == nil { + // According to openAPI spec, an object without properties and without + // additionalProperties is assumed to be a free-form object. + if c.preserveUnknownFields || len(s.Properties) == 0 { + return schema.TypeRef{ + NamedType: &deducedName, + } + } + + // If properties are specified, do not implicitly allow unknown + // fields + return schema.TypeRef{} + } else if s.AdditionalProperties.Schema != nil { + // Unknown fields use the referred schema + return c.makeOpenAPIRef(s.AdditionalProperties.Schema) + + } else if s.AdditionalProperties.Allows { + // A boolean instead of a schema was provided. Deduce the + // type from the value provided at runtime. + return schema.TypeRef{ + NamedType: &deducedName, + } + } else { + // Additional Properties are explicitly disallowed by the user. + // Ensure element type is empty. + return schema.TypeRef{} + } + }() + + relationship, err := getMapElementRelationship(s.Extensions) + if err != nil { + c.reportError(err.Error()) + } + + return &schema.Map{ + Fields: fields, + ElementRelationship: relationship, + ElementType: elementType, + } +} + +func (c *convert) parseList(s *spec.Schema) *schema.List { + relationship, mapKeys, err := getListElementRelationship(s.Extensions) + if err != nil { + c.reportError(err.Error()) + } + elementType := func() schema.TypeRef { + if s.Items != nil { + if s.Items.Schema == nil || s.Items.Len() != 1 { + c.reportError("structural schema arrays must have exactly one member subtype") + return schema.TypeRef{ + NamedType: &deducedName, + } + } + + subSchema := s.Items.Schema + if subSchema == nil { + subSchema = &s.Items.Schemas[0] + } + return c.makeOpenAPIRef(subSchema) + } else if len(s.Type) > 0 && len(s.Type[0]) > 0 { + c.reportError("`items` must be specified on arrays") + } + + // A list with no items specified is treated as "untyped". + return schema.TypeRef{ + NamedType: &untypedName, + } + + }() + + return &schema.List{ + ElementRelationship: relationship, + Keys: mapKeys, + ElementType: elementType, + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/schemaconv/proto_models.go b/vendor/k8s.io/kube-openapi/pkg/schemaconv/proto_models.go new file mode 100644 index 0000000000..2c6fd76a91 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/schemaconv/proto_models.go @@ -0,0 +1,178 @@ +/* +Copyright 2022 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 schemaconv + +import ( + "errors" + "path" + "strings" + + "k8s.io/kube-openapi/pkg/util/proto" + "sigs.k8s.io/structured-merge-diff/v4/schema" +) + +// ToSchema converts openapi definitions into a schema suitable for structured +// merge (i.e. kubectl apply v2). +func ToSchema(models proto.Models) (*schema.Schema, error) { + return ToSchemaWithPreserveUnknownFields(models, false) +} + +// ToSchemaWithPreserveUnknownFields converts openapi definitions into a schema suitable for structured +// merge (i.e. kubectl apply v2), it will preserve unknown fields if specified. +func ToSchemaWithPreserveUnknownFields(models proto.Models, preserveUnknownFields bool) (*schema.Schema, error) { + c := convert{ + preserveUnknownFields: preserveUnknownFields, + output: &schema.Schema{}, + } + for _, name := range models.ListModels() { + model := models.LookupModel(name) + + var a schema.Atom + c2 := c.push(name, &a) + model.Accept(c2) + c.pop(c2) + + c.insertTypeDef(name, a) + } + + if len(c.errorMessages) > 0 { + return nil, errors.New(strings.Join(c.errorMessages, "\n")) + } + + c.addCommonTypes() + return c.output, nil +} + +func (c *convert) makeRef(model proto.Schema, preserveUnknownFields bool) schema.TypeRef { + var tr schema.TypeRef + if r, ok := model.(*proto.Ref); ok { + if r.Reference() == "io.k8s.apimachinery.pkg.runtime.RawExtension" { + return schema.TypeRef{ + NamedType: &untypedName, + } + } + // reference a named type + _, n := path.Split(r.Reference()) + tr.NamedType = &n + + mapRelationship, err := getMapElementRelationship(model.GetExtensions()) + + if err != nil { + c.reportError(err.Error()) + } + + // empty string means unset. + if len(mapRelationship) > 0 { + tr.ElementRelationship = &mapRelationship + } + } else { + // compute the type inline + c2 := c.push("inlined in "+c.currentName, &tr.Inlined) + c2.preserveUnknownFields = preserveUnknownFields + model.Accept(c2) + c.pop(c2) + + if tr == (schema.TypeRef{}) { + // emit warning? + tr.NamedType = &untypedName + } + } + return tr +} + +func (c *convert) VisitKind(k *proto.Kind) { + preserveUnknownFields := c.preserveUnknownFields + if p, ok := k.GetExtensions()["x-kubernetes-preserve-unknown-fields"]; ok && p == true { + preserveUnknownFields = true + } + + a := c.top() + a.Map = &schema.Map{} + for _, name := range k.FieldOrder { + member := k.Fields[name] + tr := c.makeRef(member, preserveUnknownFields) + a.Map.Fields = append(a.Map.Fields, schema.StructField{ + Name: name, + Type: tr, + Default: member.GetDefault(), + }) + } + + unions, err := makeUnions(k.GetExtensions()) + if err != nil { + c.reportError(err.Error()) + return + } + // TODO: We should check that the fields and discriminator + // specified in the union are actual fields in the struct. + a.Map.Unions = unions + + if preserveUnknownFields { + a.Map.ElementType = schema.TypeRef{ + NamedType: &deducedName, + } + } + + a.Map.ElementRelationship, err = getMapElementRelationship(k.GetExtensions()) + if err != nil { + c.reportError(err.Error()) + } +} + +func (c *convert) VisitArray(a *proto.Array) { + relationship, mapKeys, err := getListElementRelationship(a.GetExtensions()) + if err != nil { + c.reportError(err.Error()) + } + + atom := c.top() + atom.List = &schema.List{ + ElementType: c.makeRef(a.SubType, c.preserveUnknownFields), + ElementRelationship: relationship, + Keys: mapKeys, + } +} + +func (c *convert) VisitMap(m *proto.Map) { + relationship, err := getMapElementRelationship(m.GetExtensions()) + if err != nil { + c.reportError(err.Error()) + } + + a := c.top() + a.Map = &schema.Map{ + ElementType: c.makeRef(m.SubType, c.preserveUnknownFields), + ElementRelationship: relationship, + } +} + +func (c *convert) VisitPrimitive(p *proto.Primitive) { + a := c.top() + if c.currentName == quantityResource { + a.Scalar = ptr(schema.Scalar("untyped")) + } else { + *a = convertPrimitive(p.Type, p.Format) + } +} + +func (c *convert) VisitArbitrary(a *proto.Arbitrary) { + *c.top() = deducedDef.Atom +} + +func (c *convert) VisitReference(proto.Reference) { + // Do nothing, we handle references specially +} diff --git a/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go b/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go index bec0e78097..799d866d51 100644 --- a/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go +++ b/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go @@ -17,43 +17,18 @@ limitations under the License. package schemaconv import ( - "errors" "fmt" - "path" "sort" - "strings" - "k8s.io/kube-openapi/pkg/util/proto" "sigs.k8s.io/structured-merge-diff/v4/schema" ) const ( - quantityResource = "io.k8s.apimachinery.pkg.api.resource.Quantity" + quantityResource = "io.k8s.apimachinery.pkg.api.resource.Quantity" + rawExtensionResource = "io.k8s.apimachinery.pkg.runtime.RawExtension" ) -// ToSchema converts openapi definitions into a schema suitable for structured -// merge (i.e. kubectl apply v2). -func ToSchema(models proto.Models) (*schema.Schema, error) { - return ToSchemaWithPreserveUnknownFields(models, false) -} - -// ToSchemaWithPreserveUnknownFields converts openapi definitions into a schema suitable for structured -// merge (i.e. kubectl apply v2), it will preserve unknown fields if specified. -func ToSchemaWithPreserveUnknownFields(models proto.Models, preserveUnknownFields bool) (*schema.Schema, error) { - c := convert{ - input: models, - preserveUnknownFields: preserveUnknownFields, - output: &schema.Schema{}, - } - if err := c.convertAll(); err != nil { - return nil, err - } - c.addCommonTypes() - return c.output, nil -} - type convert struct { - input proto.Models preserveUnknownFields bool output *schema.Schema @@ -64,7 +39,6 @@ type convert struct { func (c *convert) push(name string, a *schema.Atom) *convert { return &convert{ - input: c.input, preserveUnknownFields: c.preserveUnknownFields, output: c.output, currentName: name, @@ -78,30 +52,17 @@ func (c *convert) pop(c2 *convert) { c.errorMessages = append(c.errorMessages, c2.errorMessages...) } -func (c *convert) convertAll() error { - for _, name := range c.input.ListModels() { - model := c.input.LookupModel(name) - c.insertTypeDef(name, model) - } - if len(c.errorMessages) > 0 { - return errors.New(strings.Join(c.errorMessages, "\n")) - } - return nil -} - func (c *convert) reportError(format string, args ...interface{}) { c.errorMessages = append(c.errorMessages, c.currentName+": "+fmt.Sprintf(format, args...), ) } -func (c *convert) insertTypeDef(name string, model proto.Schema) { +func (c *convert) insertTypeDef(name string, atom schema.Atom) { def := schema.TypeDef{ Name: name, + Atom: atom, } - c2 := c.push(name, &def.Atom) - model.Accept(c2) - c.pop(c2) if def.Atom == (schema.Atom{}) { // This could happen if there were a top-level reference. return @@ -156,46 +117,6 @@ var deducedDef schema.TypeDef = schema.TypeDef{ }, } -func (c *convert) makeRef(model proto.Schema, preserveUnknownFields bool) schema.TypeRef { - var tr schema.TypeRef - if r, ok := model.(*proto.Ref); ok { - if r.Reference() == "io.k8s.apimachinery.pkg.runtime.RawExtension" { - return schema.TypeRef{ - NamedType: &untypedName, - } - } - // reference a named type - _, n := path.Split(r.Reference()) - tr.NamedType = &n - - ext := model.GetExtensions() - if val, ok := ext["x-kubernetes-map-type"]; ok { - switch val { - case "atomic": - relationship := schema.Atomic - tr.ElementRelationship = &relationship - case "granular": - relationship := schema.Separable - tr.ElementRelationship = &relationship - default: - c.reportError("unknown map type %v", val) - } - } - } else { - // compute the type inline - c2 := c.push("inlined in "+c.currentName, &tr.Inlined) - c2.preserveUnknownFields = preserveUnknownFields - model.Accept(c2) - c.pop(c2) - - if tr == (schema.TypeRef{}) { - // emit warning? - tr.NamedType = &untypedName - } - } - return tr -} - func makeUnions(extensions map[string]interface{}) ([]schema.Union, error) { schemaUnions := []schema.Union{} if iunions, ok := extensions["x-kubernetes-unions"]; ok { @@ -299,52 +220,6 @@ func makeUnion(extensions map[string]interface{}) (schema.Union, error) { return union, nil } -func (c *convert) VisitKind(k *proto.Kind) { - preserveUnknownFields := c.preserveUnknownFields - if p, ok := k.GetExtensions()["x-kubernetes-preserve-unknown-fields"]; ok && p == true { - preserveUnknownFields = true - } - - a := c.top() - a.Map = &schema.Map{} - for _, name := range k.FieldOrder { - member := k.Fields[name] - tr := c.makeRef(member, preserveUnknownFields) - a.Map.Fields = append(a.Map.Fields, schema.StructField{ - Name: name, - Type: tr, - Default: member.GetDefault(), - }) - } - - unions, err := makeUnions(k.GetExtensions()) - if err != nil { - c.reportError(err.Error()) - return - } - // TODO: We should check that the fields and discriminator - // specified in the union are actual fields in the struct. - a.Map.Unions = unions - - if preserveUnknownFields { - a.Map.ElementType = schema.TypeRef{ - NamedType: &deducedName, - } - } - - ext := k.GetExtensions() - if val, ok := ext["x-kubernetes-map-type"]; ok { - switch val { - case "atomic": - a.Map.ElementRelationship = schema.Atomic - case "granular": - a.Map.ElementRelationship = schema.Separable - default: - c.reportError("unknown map type %v", val) - } - } -} - func toStringSlice(o interface{}) (out []string, ok bool) { switch t := o.(type) { case []interface{}: @@ -355,117 +230,108 @@ func toStringSlice(o interface{}) (out []string, ok bool) { } } return out, true + case []string: + return t, true } return nil, false } -func (c *convert) VisitArray(a *proto.Array) { - atom := c.top() - atom.List = &schema.List{ - ElementRelationship: schema.Atomic, - } - l := atom.List - l.ElementType = c.makeRef(a.SubType, c.preserveUnknownFields) - - ext := a.GetExtensions() +func ptr(s schema.Scalar) *schema.Scalar { return &s } - if val, ok := ext["x-kubernetes-list-type"]; ok { - if val == "atomic" { - l.ElementRelationship = schema.Atomic - } else if val == "set" { - l.ElementRelationship = schema.Associative - } else if val == "map" { - l.ElementRelationship = schema.Associative - if keys, ok := ext["x-kubernetes-list-map-keys"]; ok { - if keyNames, ok := toStringSlice(keys); ok { - l.Keys = keyNames - } else { - c.reportError("uninterpreted map keys: %#v", keys) - } - } else { - c.reportError("missing map keys") - } - } else { - c.reportError("unknown list type %v", val) - l.ElementRelationship = schema.Atomic - } - } else if val, ok := ext["x-kubernetes-patch-strategy"]; ok { - if val == "merge" || val == "merge,retainKeys" { - l.ElementRelationship = schema.Associative - if key, ok := ext["x-kubernetes-patch-merge-key"]; ok { - if keyName, ok := key.(string); ok { - l.Keys = []string{keyName} - } else { - c.reportError("uninterpreted merge key: %#v", key) - } - } else { - // It's not an error for this to be absent, it - // means it's a set. - } - } else if val == "retainKeys" { - } else { - c.reportError("unknown patch strategy %v", val) - l.ElementRelationship = schema.Atomic +// Basic conversion functions to convert OpenAPI schema definitions to +// SMD Schema atoms +func convertPrimitive(typ string, format string) (a schema.Atom) { + switch typ { + case "integer": + a.Scalar = ptr(schema.Numeric) + case "number": + a.Scalar = ptr(schema.Numeric) + case "string": + switch format { + case "": + a.Scalar = ptr(schema.String) + case "byte": + // byte really means []byte and is encoded as a string. + a.Scalar = ptr(schema.String) + case "int-or-string": + a.Scalar = ptr(schema.Scalar("untyped")) + case "date-time": + a.Scalar = ptr(schema.Scalar("untyped")) + default: + a.Scalar = ptr(schema.Scalar("untyped")) } + case "boolean": + a.Scalar = ptr(schema.Boolean) + default: + a.Scalar = ptr(schema.Scalar("untyped")) } -} -func (c *convert) VisitMap(m *proto.Map) { - a := c.top() - a.Map = &schema.Map{} - a.Map.ElementType = c.makeRef(m.SubType, c.preserveUnknownFields) + return a +} - ext := m.GetExtensions() - if val, ok := ext["x-kubernetes-map-type"]; ok { +func getListElementRelationship(ext map[string]any) (schema.ElementRelationship, []string, error) { + if val, ok := ext["x-kubernetes-list-type"]; ok { switch val { case "atomic": - a.Map.ElementRelationship = schema.Atomic - case "granular": - a.Map.ElementRelationship = schema.Separable + return schema.Atomic, nil, nil + case "set": + return schema.Associative, nil, nil + case "map": + keys, ok := ext["x-kubernetes-list-map-keys"] + + if !ok { + return schema.Associative, nil, fmt.Errorf("missing map keys") + } + + keyNames, ok := toStringSlice(keys) + if !ok { + return schema.Associative, nil, fmt.Errorf("uninterpreted map keys: %#v", keys) + } + + return schema.Associative, keyNames, nil default: - c.reportError("unknown map type %v", val) + return schema.Atomic, nil, fmt.Errorf("unknown list type %v", val) } - } -} + } else if val, ok := ext["x-kubernetes-patch-strategy"]; ok { + switch val { + case "merge", "merge,retainKeys": + if key, ok := ext["x-kubernetes-patch-merge-key"]; ok { + keyName, ok := key.(string) -func ptr(s schema.Scalar) *schema.Scalar { return &s } + if !ok { + return schema.Associative, nil, fmt.Errorf("uninterpreted merge key: %#v", key) + } -func (c *convert) VisitPrimitive(p *proto.Primitive) { - a := c.top() - if c.currentName == quantityResource { - a.Scalar = ptr(schema.Scalar("untyped")) - } else { - switch p.Type { - case proto.Integer: - a.Scalar = ptr(schema.Numeric) - case proto.Number: - a.Scalar = ptr(schema.Numeric) - case proto.String: - switch p.Format { - case "": - a.Scalar = ptr(schema.String) - case "byte": - // byte really means []byte and is encoded as a string. - a.Scalar = ptr(schema.String) - case "int-or-string": - a.Scalar = ptr(schema.Scalar("untyped")) - case "date-time": - a.Scalar = ptr(schema.Scalar("untyped")) - default: - a.Scalar = ptr(schema.Scalar("untyped")) + return schema.Associative, []string{keyName}, nil } - case proto.Boolean: - a.Scalar = ptr(schema.Boolean) + // It's not an error for x-kubernetes-patch-merge-key to be absent, + // it means it's a set + return schema.Associative, nil, nil + case "retainKeys": + return schema.Atomic, nil, nil default: - a.Scalar = ptr(schema.Scalar("untyped")) + return schema.Atomic, nil, fmt.Errorf("unknown patch strategy %v", val) } } -} -func (c *convert) VisitArbitrary(a *proto.Arbitrary) { - *c.top() = deducedDef.Atom + // Treat as atomic by default + return schema.Atomic, nil, nil } -func (c *convert) VisitReference(proto.Reference) { - // Do nothing, we handle references specially +// Returns map element relationship if specified, or empty string if unspecified +func getMapElementRelationship(ext map[string]any) (schema.ElementRelationship, error) { + val, ok := ext["x-kubernetes-map-type"] + if !ok { + // unset Map element relationship + return "", nil + } + + switch val { + case "atomic": + return schema.Atomic, nil + case "granular": + return schema.Separable, nil + default: + return "", fmt.Errorf("unknown map type %v", val) + } } diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go b/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go index 51dac4bdf0..699291f1d8 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go @@ -18,7 +18,10 @@ package spec3 import ( "encoding/json" + "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -41,6 +44,9 @@ func (e *Encoding) MarshalJSON() ([]byte, error) { } func (e *Encoding) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, e) + } if err := json.Unmarshal(data, &e.EncodingProps); err != nil { return err } @@ -50,6 +56,20 @@ func (e *Encoding) UnmarshalJSON(data []byte) error { return nil } +func (e *Encoding) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + EncodingProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + + e.Extensions = internal.SanitizeExtensions(x.Extensions) + e.EncodingProps = x.EncodingProps + return nil +} + type EncodingProps struct { // Content Type for encoding a specific property ContentType string `json:"contentType,omitempty"` @@ -58,7 +78,7 @@ type EncodingProps struct { // Describes how a specific property value will be serialized depending on its type Style string `json:"style,omitempty"` // When this is true, property values of type array or object generate separate parameters for each value of the array, or key-value-pair of the map. For other types of properties this property has no effect - Explode string `json:"explode,omitempty"` + Explode bool `json:"explode,omitempty"` // AllowReserved determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986 AllowReserved bool `json:"allowReserved,omitempty"` } diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/example.go b/vendor/k8s.io/kube-openapi/pkg/spec3/example.go index 0f5ab983cc..03b8727170 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/example.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/example.go @@ -19,8 +19,11 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + + "k8s.io/kube-openapi/pkg/validation/spec" ) // Example https://swagger.io/specification/#example-object @@ -49,6 +52,9 @@ func (e *Example) MarshalJSON() ([]byte, error) { } func (e *Example) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, e) + } if err := json.Unmarshal(data, &e.Refable); err != nil { return err } @@ -61,6 +67,23 @@ func (e *Example) UnmarshalJSON(data []byte) error { return nil } +func (e *Example) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ExampleProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&e.Ref.Ref, x.Extensions); err != nil { + return err + } + e.Extensions = internal.SanitizeExtensions(x.Extensions) + e.ExampleProps = x.ExampleProps + + return nil +} + type ExampleProps struct { // Summary holds a short description of the example Summary string `json:"summary,omitempty"` diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go b/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go index 117113e7a7..e79956721a 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go @@ -18,8 +18,11 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" + "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) type ExternalDocumentation struct { @@ -48,6 +51,9 @@ func (e *ExternalDocumentation) MarshalJSON() ([]byte, error) { } func (e *ExternalDocumentation) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, e) + } if err := json.Unmarshal(data, &e.ExternalDocumentationProps); err != nil { return err } @@ -56,3 +62,16 @@ func (e *ExternalDocumentation) UnmarshalJSON(data []byte) error { } return nil } + +func (e *ExternalDocumentation) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ExternalDocumentationProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + e.Extensions = internal.SanitizeExtensions(x.Extensions) + e.ExternalDocumentationProps = x.ExternalDocumentationProps + return nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/fuzz.go b/vendor/k8s.io/kube-openapi/pkg/spec3/fuzz.go new file mode 100644 index 0000000000..bc19dd48ed --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/fuzz.go @@ -0,0 +1,254 @@ +package spec3 + +import ( + "math/rand" + "strings" + + fuzz "github.com/google/gofuzz" + + "k8s.io/kube-openapi/pkg/validation/spec" +) + +// refChance is the chance that a particular component will use a $ref +// instead of fuzzed. Expressed as a fraction 1/n, currently there is +// a 1/3 chance that a ref will be used. +const refChance = 3 + +const alphaNumChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + +func randAlphanumString() string { + arr := make([]string, rand.Intn(10)+5) + for i := 0; i < len(arr); i++ { + arr[i] = string(alphaNumChars[rand.Intn(len(alphaNumChars))]) + } + return strings.Join(arr, "") +} + +var OpenAPIV3FuzzFuncs []interface{} = []interface{}{ + func(s *string, c fuzz.Continue) { + // All OpenAPI V3 map keys must follow the corresponding + // regex. Note that this restricts the range for all other + // string values as well. + str := randAlphanumString() + *s = str + }, + func(o *OpenAPI, c fuzz.Continue) { + c.FuzzNoCustom(o) + o.Version = "3.0.0" + }, + func(r *interface{}, c fuzz.Continue) { + switch c.Intn(3) { + case 0: + *r = nil + case 1: + n := c.RandString() + "x" + *r = n + case 2: + n := c.Float64() + *r = n + } + }, + func(v **spec.Info, c fuzz.Continue) { + // Info is never nil + *v = &spec.Info{} + c.FuzzNoCustom(*v) + (*v).Title = c.RandString() + "x" + }, + func(v *Paths, c fuzz.Continue) { + c.Fuzz(&v.VendorExtensible) + num := c.Intn(5) + if num > 0 { + v.Paths = make(map[string]*Path) + } + for i := 0; i < num; i++ { + val := Path{} + c.Fuzz(&val) + v.Paths["/"+c.RandString()] = &val + } + }, + func(v *SecurityScheme, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Refable) + return + } + switch c.Intn(4) { + case 0: + v.Type = "apiKey" + v.Name = c.RandString() + "x" + switch c.Intn(3) { + case 0: + v.In = "query" + case 1: + v.In = "header" + case 2: + v.In = "cookie" + } + case 1: + v.Type = "http" + case 2: + v.Type = "oauth2" + v.Flows = make(map[string]*OAuthFlow) + flow := OAuthFlow{} + flow.AuthorizationUrl = c.RandString() + "x" + v.Flows["implicit"] = &flow + flow.Scopes = make(map[string]string) + flow.Scopes["foo"] = "bar" + case 3: + v.Type = "openIdConnect" + v.OpenIdConnectUrl = "https://" + c.RandString() + } + v.Scheme = "basic" + }, + func(v *spec.Ref, c fuzz.Continue) { + switch c.Intn(7) { + case 0: + *v = spec.MustCreateRef("#/components/schemas/" + randAlphanumString()) + case 1: + *v = spec.MustCreateRef("#/components/responses/" + randAlphanumString()) + case 2: + *v = spec.MustCreateRef("#/components/headers/" + randAlphanumString()) + case 3: + *v = spec.MustCreateRef("#/components/securitySchemes/" + randAlphanumString()) + case 5: + *v = spec.MustCreateRef("#/components/parameters/" + randAlphanumString()) + case 6: + *v = spec.MustCreateRef("#/components/requestBodies/" + randAlphanumString()) + } + }, + func(v *Parameter, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Refable) + return + } + c.Fuzz(&v.ParameterProps) + c.Fuzz(&v.VendorExtensible) + + switch c.Intn(3) { + case 0: + // Header param + v.In = "query" + case 1: + v.In = "header" + case 2: + v.In = "cookie" + } + }, + func(v *RequestBody, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Refable) + return + } + c.Fuzz(&v.RequestBodyProps) + c.Fuzz(&v.VendorExtensible) + }, + func(v *Header, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Refable) + return + } + c.Fuzz(&v.HeaderProps) + c.Fuzz(&v.VendorExtensible) + }, + func(v *ResponsesProps, c fuzz.Continue) { + c.Fuzz(&v.Default) + n := c.Intn(5) + for i := 0; i < n; i++ { + r2 := Response{} + c.Fuzz(&r2) + // HTTP Status code in 100-599 Range + code := c.Intn(500) + 100 + v.StatusCodeResponses = make(map[int]*Response) + v.StatusCodeResponses[code] = &r2 + } + }, + func(v *Response, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Refable) + return + } + c.Fuzz(&v.ResponseProps) + c.Fuzz(&v.VendorExtensible) + }, + func(v *spec.Extensions, c fuzz.Continue) { + numChildren := c.Intn(5) + for i := 0; i < numChildren; i++ { + if *v == nil { + *v = spec.Extensions{} + } + (*v)["x-"+c.RandString()] = c.RandString() + } + }, + func(v *spec.ExternalDocumentation, c fuzz.Continue) { + c.Fuzz(&v.Description) + v.URL = "https://" + randAlphanumString() + }, + func(v *spec.SchemaURL, c fuzz.Continue) { + *v = spec.SchemaURL("https://" + randAlphanumString()) + }, + func(v *spec.SchemaOrBool, c fuzz.Continue) { + *v = spec.SchemaOrBool{} + + if c.RandBool() { + v.Allows = c.RandBool() + } else { + v.Schema = &spec.Schema{} + v.Allows = true + c.Fuzz(&v.Schema) + } + }, + func(v *spec.SchemaOrArray, c fuzz.Continue) { + *v = spec.SchemaOrArray{} + if c.RandBool() { + schema := spec.Schema{} + c.Fuzz(&schema) + v.Schema = &schema + } else { + v.Schemas = []spec.Schema{} + numChildren := c.Intn(5) + for i := 0; i < numChildren; i++ { + schema := spec.Schema{} + c.Fuzz(&schema) + v.Schemas = append(v.Schemas, schema) + } + + } + + }, + func(v *spec.SchemaOrStringArray, c fuzz.Continue) { + if c.RandBool() { + *v = spec.SchemaOrStringArray{} + if c.RandBool() { + c.Fuzz(&v.Property) + } else { + c.Fuzz(&v.Schema) + } + } + }, + func(v *spec.Schema, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Ref) + return + } + if c.RandBool() { + // file schema + c.Fuzz(&v.Default) + c.Fuzz(&v.Description) + c.Fuzz(&v.Example) + c.Fuzz(&v.ExternalDocs) + + c.Fuzz(&v.Format) + c.Fuzz(&v.ReadOnly) + c.Fuzz(&v.Required) + c.Fuzz(&v.Title) + v.Type = spec.StringOrArray{"file"} + + } else { + // normal schema + c.Fuzz(&v.SchemaProps) + c.Fuzz(&v.SwaggerSchemaProps) + c.Fuzz(&v.VendorExtensible) + c.Fuzz(&v.ExtraProps) + } + + }, +} diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/header.go b/vendor/k8s.io/kube-openapi/pkg/spec3/header.go index cead4b15d1..ee5a30f797 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/header.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/header.go @@ -20,6 +20,8 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -50,6 +52,9 @@ func (h *Header) MarshalJSON() ([]byte, error) { } func (h *Header) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, h) + } if err := json.Unmarshal(data, &h.Refable); err != nil { return err } @@ -63,6 +68,22 @@ func (h *Header) UnmarshalJSON(data []byte) error { return nil } +func (h *Header) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + HeaderProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&h.Ref.Ref, x.Extensions); err != nil { + return err + } + h.Extensions = internal.SanitizeExtensions(x.Extensions) + h.HeaderProps = x.HeaderProps + return nil +} + // HeaderProps a struct that describes a header object type HeaderProps struct { // Description holds a brief description of the parameter diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go b/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go index 828fd8dc56..d390e69bcf 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go @@ -18,7 +18,10 @@ package spec3 import ( "encoding/json" + "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -44,6 +47,9 @@ func (m *MediaType) MarshalJSON() ([]byte, error) { } func (m *MediaType) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, m) + } if err := json.Unmarshal(data, &m.MediaTypeProps); err != nil { return err } @@ -53,10 +59,24 @@ func (m *MediaType) UnmarshalJSON(data []byte) error { return nil } +func (m *MediaType) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + MediaTypeProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + m.Extensions = internal.SanitizeExtensions(x.Extensions) + m.MediaTypeProps = x.MediaTypeProps + + return nil +} + // MediaTypeProps a struct that allows you to specify content format, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#mediaTypeObject type MediaTypeProps struct { // Schema holds the schema defining the type used for the media type - Schema *spec.Schema `json:"schema,omitempty"` + Schema *spec.Schema `json:"schema,omitempty"` // Example of the media type Example interface{} `json:"example,omitempty"` // Examples of the media type. Each example object should match the media type and specific schema if present diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go b/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go index de8aa46021..28230610bd 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go @@ -19,8 +19,10 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) // Operation describes a single API operation on a path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#operationObject @@ -46,12 +48,28 @@ func (o *Operation) MarshalJSON() ([]byte, error) { // UnmarshalJSON hydrates this items instance with the data from JSON func (o *Operation) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, o) + } if err := json.Unmarshal(data, &o.OperationProps); err != nil { return err } return json.Unmarshal(data, &o.VendorExtensible) } +func (o *Operation) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + OperationProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + o.Extensions = internal.SanitizeExtensions(x.Extensions) + o.OperationProps = x.OperationProps + return nil +} + // OperationProps describes a single API operation on a path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#operationObject type OperationProps struct { // Tags holds a list of tags for API documentation control @@ -73,7 +91,7 @@ type OperationProps struct { // Deprecated declares this operation to be deprecated Deprecated bool `json:"deprecated,omitempty"` // SecurityRequirement holds a declaration of which security mechanisms can be used for this operation - SecurityRequirement []*SecurityRequirement `json:"security,omitempty"` + SecurityRequirement []map[string][]string `json:"security,omitempty"` // Servers contains an alternative server array to service this operation Servers []*Server `json:"servers,omitempty"` } diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go b/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go index 0d7180e506..613da71a6d 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go @@ -20,6 +20,8 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -50,6 +52,10 @@ func (p *Parameter) MarshalJSON() ([]byte, error) { } func (p *Parameter) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, p) + } + if err := json.Unmarshal(data, &p.Refable); err != nil { return err } @@ -63,6 +69,22 @@ func (p *Parameter) UnmarshalJSON(data []byte) error { return nil } +func (p *Parameter) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ParameterProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&p.Ref.Ref, x.Extensions); err != nil { + return err + } + p.Extensions = internal.SanitizeExtensions(x.Extensions) + p.ParameterProps = x.ParameterProps + return nil +} + // ParameterProps a struct that describes a single operation parameter, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#parameterObject type ParameterProps struct { // Name holds the name of the parameter diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/path.go b/vendor/k8s.io/kube-openapi/pkg/spec3/path.go index bc48c504de..40d9061ace 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/path.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/path.go @@ -18,10 +18,13 @@ package spec3 import ( "encoding/json" + "fmt" "strings" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) // Paths describes the available paths and operations for the API, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#pathsObject @@ -45,6 +48,9 @@ func (p *Paths) MarshalJSON() ([]byte, error) { // UnmarshalJSON hydrates this items instance with the data from JSON func (p *Paths) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, p) + } var res map[string]json.RawMessage if err := json.Unmarshal(data, &res); err != nil { return err @@ -74,6 +80,59 @@ func (p *Paths) UnmarshalJSON(data []byte) error { return nil } +func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + tok, err := dec.ReadToken() + if err != nil { + return err + } + switch k := tok.Kind(); k { + case 'n': + *p = Paths{} + return nil + case '{': + for { + tok, err := dec.ReadToken() + if err != nil { + return err + } + + if tok.Kind() == '}' { + return nil + } + + switch k := tok.String(); { + case internal.IsExtensionKey(k): + var ext any + if err := opts.UnmarshalNext(dec, &ext); err != nil { + return err + } + + if p.Extensions == nil { + p.Extensions = make(map[string]any) + } + p.Extensions[k] = ext + case len(k) > 0 && k[0] == '/': + pi := Path{} + if err := opts.UnmarshalNext(dec, &pi); err != nil { + return err + } + + if p.Paths == nil { + p.Paths = make(map[string]*Path) + } + p.Paths[k] = &pi + default: + _, err := dec.ReadValue() // skip value + if err != nil { + return err + } + } + } + default: + return fmt.Errorf("unknown JSON kind: %v", k) + } +} + // Path describes the operations available on a single path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#pathItemObject // // Note that this struct is actually a thin wrapper around PathProps to make it referable and extensible @@ -101,6 +160,9 @@ func (p *Path) MarshalJSON() ([]byte, error) { } func (p *Path) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, p) + } if err := json.Unmarshal(data, &p.Refable); err != nil { return err } @@ -113,6 +175,24 @@ func (p *Path) UnmarshalJSON(data []byte) error { return nil } +func (p *Path) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + PathProps + } + + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&p.Ref.Ref, x.Extensions); err != nil { + return err + } + p.Extensions = internal.SanitizeExtensions(x.Extensions) + p.PathProps = x.PathProps + + return nil +} + // PathProps describes the operations available on a single path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#pathItemObject type PathProps struct { // Summary holds a summary for all operations in this path diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go b/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go index 0adc628266..33267ce675 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go @@ -19,8 +19,10 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) // RequestBody describes a single request body, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#requestBodyObject @@ -50,6 +52,9 @@ func (r *RequestBody) MarshalJSON() ([]byte, error) { } func (r *RequestBody) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, r) + } if err := json.Unmarshal(data, &r.Refable); err != nil { return err } @@ -71,3 +76,19 @@ type RequestBodyProps struct { // Required determines if the request body is required in the request Required bool `json:"required,omitempty"` } + +func (r *RequestBody) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + RequestBodyProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&r.Ref.Ref, x.Extensions); err != nil { + return err + } + r.Extensions = internal.SanitizeExtensions(x.Extensions) + r.RequestBodyProps = x.RequestBodyProps + return nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/response.go b/vendor/k8s.io/kube-openapi/pkg/spec3/response.go index ccd73369f7..95b388e6c6 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/response.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/response.go @@ -18,10 +18,13 @@ package spec3 import ( "encoding/json" + "fmt" "strconv" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) // Responses holds the list of possible responses as they are returned from executing this operation @@ -46,13 +49,15 @@ func (r *Responses) MarshalJSON() ([]byte, error) { } func (r *Responses) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, r) + } if err := json.Unmarshal(data, &r.ResponsesProps); err != nil { return err } if err := json.Unmarshal(data, &r.VendorExtensible); err != nil { return err } - return nil } @@ -78,25 +83,91 @@ func (r ResponsesProps) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals responses from JSON func (r *ResponsesProps) UnmarshalJSON(data []byte) error { - var res map[string]*Response + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, r) + } + var res map[string]json.RawMessage if err := json.Unmarshal(data, &res); err != nil { - return nil + return err } if v, ok := res["default"]; ok { - r.Default = v + value := Response{} + if err := json.Unmarshal(v, &value); err != nil { + return err + } + r.Default = &value delete(res, "default") } for k, v := range res { + // Take all integral keys if nk, err := strconv.Atoi(k); err == nil { if r.StatusCodeResponses == nil { r.StatusCodeResponses = map[int]*Response{} } - r.StatusCodeResponses[nk] = v + value := Response{} + if err := json.Unmarshal(v, &value); err != nil { + return err + } + r.StatusCodeResponses[nk] = &value } } return nil } +func (r *Responses) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) (err error) { + tok, err := dec.ReadToken() + if err != nil { + return err + } + switch k := tok.Kind(); k { + case 'n': + *r = Responses{} + return nil + case '{': + for { + tok, err := dec.ReadToken() + if err != nil { + return err + } + if tok.Kind() == '}' { + return nil + } + switch k := tok.String(); { + case internal.IsExtensionKey(k): + var ext any + if err := opts.UnmarshalNext(dec, &ext); err != nil { + return err + } + + if r.Extensions == nil { + r.Extensions = make(map[string]any) + } + r.Extensions[k] = ext + case k == "default": + resp := Response{} + if err := opts.UnmarshalNext(dec, &resp); err != nil { + return err + } + r.ResponsesProps.Default = &resp + default: + if nk, err := strconv.Atoi(k); err == nil { + resp := Response{} + if err := opts.UnmarshalNext(dec, &resp); err != nil { + return err + } + + if r.StatusCodeResponses == nil { + r.StatusCodeResponses = map[int]*Response{} + } + r.StatusCodeResponses[nk] = &resp + } + } + } + default: + return fmt.Errorf("unknown JSON kind: %v", k) + } +} + // Response describes a single response from an API Operation, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#responseObject // // Note that this struct is actually a thin wrapper around ResponseProps to make it referable and extensible @@ -124,6 +195,9 @@ func (r *Response) MarshalJSON() ([]byte, error) { } func (r *Response) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, r) + } if err := json.Unmarshal(data, &r.Refable); err != nil { return err } @@ -133,7 +207,22 @@ func (r *Response) UnmarshalJSON(data []byte) error { if err := json.Unmarshal(data, &r.VendorExtensible); err != nil { return err } + return nil +} +func (r *Response) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ResponseProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&r.Ref.Ref, x.Extensions); err != nil { + return err + } + r.Extensions = internal.SanitizeExtensions(x.Extensions) + r.ResponseProps = x.ResponseProps return nil } @@ -149,7 +238,6 @@ type ResponseProps struct { Links map[string]*Link `json:"links,omitempty"` } - // Link represents a possible design-time link for a response, more at https://swagger.io/specification/#link-object type Link struct { spec.Refable @@ -175,6 +263,9 @@ func (r *Link) MarshalJSON() ([]byte, error) { } func (r *Link) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, r) + } if err := json.Unmarshal(data, &r.Refable); err != nil { return err } @@ -188,6 +279,22 @@ func (r *Link) UnmarshalJSON(data []byte) error { return nil } +func (l *Link) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + LinkProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&l.Ref.Ref, x.Extensions); err != nil { + return err + } + l.Extensions = internal.SanitizeExtensions(x.Extensions) + l.LinkProps = x.LinkProps + return nil +} + // LinkProps describes a single response from an API Operation, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#responseObject type LinkProps struct { // OperationId is the name of an existing, resolvable OAS operation diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/security_requirement.go b/vendor/k8s.io/kube-openapi/pkg/spec3/security_requirement.go deleted file mode 100644 index 0ce8924efd..0000000000 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/security_requirement.go +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright 2021 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 spec3 - -import ( - "encoding/json" - - "k8s.io/kube-openapi/pkg/validation/spec" - "github.com/go-openapi/swag" -) - -// SecurityRequirementProps describes the required security schemes to execute an operation, more at https://swagger.io/specification/#security-requirement-object -// -// Note that this struct is actually a thin wrapper around SecurityRequirementProps to make it referable and extensible -type SecurityRequirement struct { - SecurityRequirementProps - spec.VendorExtensible -} - -// MarshalJSON is a custom marshal function that knows how to encode SecurityRequirement as JSON -func (s *SecurityRequirement) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(s.SecurityRequirementProps) - if err != nil { - return nil, err - } - b2, err := json.Marshal(s.VendorExtensible) - if err != nil { - return nil, err - } - return swag.ConcatJSON(b1, b2), nil -} - -// UnmarshalJSON hydrates this items instance with the data from JSON -func (s *SecurityRequirement) UnmarshalJSON(data []byte) error { - if err := json.Unmarshal(data, &s.SecurityRequirementProps); err != nil { - return err - } - return json.Unmarshal(data, &s.VendorExtensible) -} - -// SecurityRequirementProps describes the required security schemes to execute an operation, more at https://swagger.io/specification/#security-requirement-object -type SecurityRequirementProps map[string][]string diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go b/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go index 9b1352f4e3..edf7e6de3f 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go @@ -19,8 +19,8 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/validation/spec" ) // SecurityScheme defines reusable Security Scheme Object, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securitySchemeObject diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/server.go b/vendor/k8s.io/kube-openapi/pkg/spec3/server.go index a505fb2218..d5df0a7811 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/server.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/server.go @@ -18,9 +18,11 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" - "github.com/go-openapi/swag" + "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) type Server struct { @@ -51,6 +53,10 @@ func (s *Server) MarshalJSON() ([]byte, error) { } func (s *Server) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, s) + } + if err := json.Unmarshal(data, &s.ServerProps); err != nil { return err } @@ -60,6 +66,20 @@ func (s *Server) UnmarshalJSON(data []byte) error { return nil } +func (s *Server) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ServerProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + s.Extensions = internal.SanitizeExtensions(x.Extensions) + s.ServerProps = x.ServerProps + + return nil +} + type ServerVariable struct { ServerVariableProps spec.VendorExtensible @@ -88,6 +108,9 @@ func (s *ServerVariable) MarshalJSON() ([]byte, error) { } func (s *ServerVariable) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, s) + } if err := json.Unmarshal(data, &s.ServerVariableProps); err != nil { return err } @@ -96,3 +119,17 @@ func (s *ServerVariable) UnmarshalJSON(data []byte) error { } return nil } + +func (s *ServerVariable) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ServerVariableProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + s.Extensions = internal.SanitizeExtensions(x.Extensions) + s.ServerVariableProps = x.ServerVariableProps + + return nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go b/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go index 3ff48a3c3d..bed096fb76 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go @@ -17,6 +17,10 @@ limitations under the License. package spec3 import ( + "encoding/json" + + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -35,3 +39,12 @@ type OpenAPI struct { // ExternalDocs holds additional external documentation ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"` } + +func (o *OpenAPI) UnmarshalJSON(data []byte) error { + type OpenAPIWithNoFunctions OpenAPI + p := (*OpenAPIWithNoFunctions)(o) + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, &p) + } + return json.Unmarshal(data, &p) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/util/proto/document_v3.go b/vendor/k8s.io/kube-openapi/pkg/util/proto/document_v3.go index a3f476d5d8..519dcf2eba 100644 --- a/vendor/k8s.io/kube-openapi/pkg/util/proto/document_v3.go +++ b/vendor/k8s.io/kube-openapi/pkg/util/proto/document_v3.go @@ -120,7 +120,7 @@ func (d *Definitions) ParseSchemaV3(s *openapi_v3.Schema, path *Path) (Schema, e switch s.GetType() { case object: for _, extension := range s.GetSpecificationExtension() { - if extension.Name == "x-kuberentes-group-version-kind" { + if extension.Name == "x-kubernetes-group-version-kind" { // Objects with x-kubernetes-group-version-kind are always top // level types. return d.parseV3Kind(s, path) @@ -285,7 +285,7 @@ func parseV3Interface(def *yaml.Node) (interface{}, error) { func (d *Definitions) parseV3BaseSchema(s *openapi_v3.Schema, path *Path) (*BaseSchema, error) { if s == nil { - return nil, fmt.Errorf("cannot initializae BaseSchema from nil") + return nil, fmt.Errorf("cannot initialize BaseSchema from nil") } def, err := parseV3Interface(s.GetDefault().ToRawInfo()) diff --git a/vendor/k8s.io/kube-openapi/pkg/util/trie.go b/vendor/k8s.io/kube-openapi/pkg/util/trie.go new file mode 100644 index 0000000000..a9a76c1791 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/util/trie.go @@ -0,0 +1,79 @@ +/* +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 util + +// A simple trie implementation with Add and HasPrefix methods only. +type Trie struct { + children map[byte]*Trie + wordTail bool + word string +} + +// NewTrie creates a Trie and add all strings in the provided list to it. +func NewTrie(list []string) Trie { + ret := Trie{ + children: make(map[byte]*Trie), + wordTail: false, + } + for _, v := range list { + ret.Add(v) + } + return ret +} + +// Add adds a word to this trie +func (t *Trie) Add(v string) { + root := t + for _, b := range []byte(v) { + child, exists := root.children[b] + if !exists { + child = &Trie{ + children: make(map[byte]*Trie), + wordTail: false, + } + root.children[b] = child + } + root = child + } + root.wordTail = true + root.word = v +} + +// HasPrefix returns true of v has any of the prefixes stored in this trie. +func (t *Trie) HasPrefix(v string) bool { + _, has := t.GetPrefix(v) + return has +} + +// GetPrefix is like HasPrefix but return the prefix in case of match or empty string otherwise. +func (t *Trie) GetPrefix(v string) (string, bool) { + root := t + if root.wordTail { + return root.word, true + } + for _, b := range []byte(v) { + child, exists := root.children[b] + if !exists { + return "", false + } + if child.wordTail { + return child.word, true + } + root = child + } + return "", false +} diff --git a/vendor/k8s.io/kube-openapi/pkg/util/util.go b/vendor/k8s.io/kube-openapi/pkg/util/util.go new file mode 100644 index 0000000000..6eee935b22 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/util/util.go @@ -0,0 +1,115 @@ +/* +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 util + +import ( + "reflect" + "strings" +) + +// [DEPRECATED] ToCanonicalName converts Golang package/type canonical name into REST friendly OpenAPI name. +// This method is deprecated because it has a misleading name. Please use ToRESTFriendlyName +// instead +// +// NOTE: actually the "canonical name" in this method should be named "REST friendly OpenAPI name", +// which is different from "canonical name" defined in GetCanonicalTypeName. The "canonical name" defined +// in GetCanonicalTypeName means Go type names with full package path. +// +// Examples of REST friendly OpenAPI name: +// +// Input: k8s.io/api/core/v1.Pod +// Output: io.k8s.api.core.v1.Pod +// +// Input: k8s.io/api/core/v1 +// Output: io.k8s.api.core.v1 +// +// Input: csi.storage.k8s.io/v1alpha1.CSINodeInfo +// Output: io.k8s.storage.csi.v1alpha1.CSINodeInfo +func ToCanonicalName(name string) string { + return ToRESTFriendlyName(name) +} + +// ToRESTFriendlyName converts Golang package/type canonical name into REST friendly OpenAPI name. +// +// Examples of REST friendly OpenAPI name: +// +// Input: k8s.io/api/core/v1.Pod +// Output: io.k8s.api.core.v1.Pod +// +// Input: k8s.io/api/core/v1 +// Output: io.k8s.api.core.v1 +// +// Input: csi.storage.k8s.io/v1alpha1.CSINodeInfo +// Output: io.k8s.storage.csi.v1alpha1.CSINodeInfo +func ToRESTFriendlyName(name string) string { + nameParts := strings.Split(name, "/") + // Reverse first part. e.g., io.k8s... instead of k8s.io... + if len(nameParts) > 0 && strings.Contains(nameParts[0], ".") { + parts := strings.Split(nameParts[0], ".") + for i, j := 0, len(parts)-1; i < j; i, j = i+1, j-1 { + parts[i], parts[j] = parts[j], parts[i] + } + nameParts[0] = strings.Join(parts, ".") + } + return strings.Join(nameParts, ".") +} + +// OpenAPICanonicalTypeNamer is an interface for models without Go type to seed model name. +// +// OpenAPI canonical names are Go type names with full package path, for uniquely indentifying +// a model / Go type. If a Go type is vendored from another package, only the path after "/vendor/" +// should be used. For custom resource definition (CRD), the canonical name is expected to be +// +// group/version.kind +// +// Examples of canonical name: +// +// Go type: k8s.io/kubernetes/pkg/apis/core.Pod +// CRD: csi.storage.k8s.io/v1alpha1.CSINodeInfo +// +// Example for vendored Go type: +// +// Original full path: k8s.io/kubernetes/vendor/k8s.io/api/core/v1.Pod +// Canonical name: k8s.io/api/core/v1.Pod +// +// Original full path: vendor/k8s.io/api/core/v1.Pod +// Canonical name: k8s.io/api/core/v1.Pod +type OpenAPICanonicalTypeNamer interface { + OpenAPICanonicalTypeName() string +} + +// GetCanonicalTypeName will find the canonical type name of a sample object, removing +// the "vendor" part of the path +func GetCanonicalTypeName(model interface{}) string { + if namer, ok := model.(OpenAPICanonicalTypeNamer); ok { + return namer.OpenAPICanonicalTypeName() + } + t := reflect.TypeOf(model) + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + if t.PkgPath() == "" { + return t.Name() + } + path := t.PkgPath() + if strings.Contains(path, "/vendor/") { + path = path[strings.Index(path, "/vendor/")+len("/vendor/"):] + } else if strings.HasPrefix(path, "vendor/") { + path = strings.TrimPrefix(path, "vendor/") + } + return path + "." + t.Name() +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/errors/.gitignore b/vendor/k8s.io/kube-openapi/pkg/validation/errors/.gitignore new file mode 100644 index 0000000000..dd91ed6a04 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/errors/.gitignore @@ -0,0 +1,2 @@ +secrets.yml +coverage.out diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/errors/LICENSE b/vendor/k8s.io/kube-openapi/pkg/validation/errors/LICENSE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/errors/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/errors/api.go b/vendor/k8s.io/kube-openapi/pkg/validation/errors/api.go new file mode 100644 index 0000000000..e0b310044a --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/errors/api.go @@ -0,0 +1,46 @@ +// Copyright 2015 go-swagger maintainers +// +// 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 errors + +import ( + "fmt" +) + +// Error represents a error interface all swagger framework errors implement +type Error interface { + error + Code() int32 +} + +type apiError struct { + code int32 + message string +} + +func (a *apiError) Error() string { + return a.message +} + +func (a *apiError) Code() int32 { + return a.code +} + +// New creates a new API error with a code and a message +func New(code int32, message string, args ...interface{}) Error { + if len(args) > 0 { + return &apiError{code, fmt.Sprintf(message, args...)} + } + return &apiError{code, message} +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/errors/doc.go b/vendor/k8s.io/kube-openapi/pkg/validation/errors/doc.go new file mode 100644 index 0000000000..af01190ce6 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/errors/doc.go @@ -0,0 +1,26 @@ +// Copyright 2015 go-swagger maintainers +// +// 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 errors provides an Error interface and several concrete types +implementing this interface to manage API errors and JSON-schema validation +errors. + +A middleware handler ServeError() is provided to serve the errors types +it defines. + +It is used throughout the various go-openapi toolkit libraries +(https://github.com/go-openapi). +*/ +package errors diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/errors/headers.go b/vendor/k8s.io/kube-openapi/pkg/validation/errors/headers.go new file mode 100644 index 0000000000..3da85c3672 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/errors/headers.go @@ -0,0 +1,44 @@ +// Copyright 2015 go-swagger maintainers +// +// 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 errors + +// Validation represents a failure of a precondition +type Validation struct { + code int32 + Name string + In string + Value interface{} + Valid interface{} + message string + Values []interface{} +} + +func (e *Validation) Error() string { + return e.message +} + +// Code the error code +func (e *Validation) Code() int32 { + return e.code +} + +// ValidateName produces an error message name for an aliased property +func (e *Validation) ValidateName(name string) *Validation { + if e.Name == "" && name != "" { + e.Name = name + e.message = name + e.message + } + return e +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/errors/schema.go b/vendor/k8s.io/kube-openapi/pkg/validation/errors/schema.go new file mode 100644 index 0000000000..65f133e9ee --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/errors/schema.go @@ -0,0 +1,573 @@ +// Copyright 2015 go-swagger maintainers +// +// 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 errors + +import ( + "fmt" + "strings" +) + +const ( + invalidType = "%s is an invalid type name" + typeFail = "%s in %s must be of type %s" + typeFailWithData = "%s in %s must be of type %s: %q" + typeFailWithError = "%s in %s must be of type %s, because: %s" + requiredFail = "%s in %s is required" + tooLongMessage = "%s in %s should be at most %d chars long" + tooShortMessage = "%s in %s should be at least %d chars long" + patternFail = "%s in %s should match '%s'" + enumFail = "%s in %s should be one of %v" + multipleOfFail = "%s in %s should be a multiple of %v" + maxIncFail = "%s in %s should be less than or equal to %v" + maxExcFail = "%s in %s should be less than %v" + minIncFail = "%s in %s should be greater than or equal to %v" + minExcFail = "%s in %s should be greater than %v" + uniqueFail = "%s in %s shouldn't contain duplicates" + maxItemsFail = "%s in %s should have at most %d items" + minItemsFail = "%s in %s should have at least %d items" + typeFailNoIn = "%s must be of type %s" + typeFailWithDataNoIn = "%s must be of type %s: %q" + typeFailWithErrorNoIn = "%s must be of type %s, because: %s" + requiredFailNoIn = "%s is required" + tooLongMessageNoIn = "%s should be at most %d chars long" + tooShortMessageNoIn = "%s should be at least %d chars long" + patternFailNoIn = "%s should match '%s'" + enumFailNoIn = "%s should be one of %v" + multipleOfFailNoIn = "%s should be a multiple of %v" + maxIncFailNoIn = "%s should be less than or equal to %v" + maxExcFailNoIn = "%s should be less than %v" + minIncFailNoIn = "%s should be greater than or equal to %v" + minExcFailNoIn = "%s should be greater than %v" + uniqueFailNoIn = "%s shouldn't contain duplicates" + maxItemsFailNoIn = "%s should have at most %d items" + minItemsFailNoIn = "%s should have at least %d items" + noAdditionalItems = "%s in %s can't have additional items" + noAdditionalItemsNoIn = "%s can't have additional items" + tooFewProperties = "%s in %s should have at least %d properties" + tooFewPropertiesNoIn = "%s should have at least %d properties" + tooManyProperties = "%s in %s should have at most %d properties" + tooManyPropertiesNoIn = "%s should have at most %d properties" + unallowedProperty = "%s.%s in %s is a forbidden property" + unallowedPropertyNoIn = "%s.%s is a forbidden property" + failedAllPatternProps = "%s.%s in %s failed all pattern properties" + failedAllPatternPropsNoIn = "%s.%s failed all pattern properties" + multipleOfMustBePositive = "factor MultipleOf declared for %s must be positive: %v" +) + +// All code responses can be used to differentiate errors for different handling +// by the consuming program +const ( + // CompositeErrorCode remains 422 for backwards-compatibility + // and to separate it from validation errors with cause + CompositeErrorCode = 422 + // InvalidTypeCode is used for any subclass of invalid types + InvalidTypeCode = 600 + iota + RequiredFailCode + TooLongFailCode + TooShortFailCode + PatternFailCode + EnumFailCode + MultipleOfFailCode + MaxFailCode + MinFailCode + UniqueFailCode + MaxItemsFailCode + MinItemsFailCode + NoAdditionalItemsCode + TooFewPropertiesCode + TooManyPropertiesCode + UnallowedPropertyCode + FailedAllPatternPropsCode + MultipleOfMustBePositiveCode +) + +// CompositeError is an error that groups several errors together +type CompositeError struct { + Errors []error + code int32 + message string +} + +// Code for this error +func (c *CompositeError) Code() int32 { + return c.code +} + +func (c *CompositeError) Error() string { + if len(c.Errors) > 0 { + msgs := []string{c.message + ":"} + for _, e := range c.Errors { + msgs = append(msgs, e.Error()) + } + return strings.Join(msgs, "\n") + } + return c.message +} + +// CompositeValidationError an error to wrap a bunch of other errors +func CompositeValidationError(errors ...error) *CompositeError { + return &CompositeError{ + code: CompositeErrorCode, + Errors: append([]error{}, errors...), + message: "validation failure list", + } +} + +// FailedAllPatternProperties an error for when the property doesn't match a pattern +func FailedAllPatternProperties(name, in, key string) *Validation { + msg := fmt.Sprintf(failedAllPatternProps, name, key, in) + if in == "" { + msg = fmt.Sprintf(failedAllPatternPropsNoIn, name, key) + } + return &Validation{ + code: FailedAllPatternPropsCode, + Name: name, + In: in, + Value: key, + message: msg, + } +} + +// PropertyNotAllowed an error for when the property doesn't match a pattern +func PropertyNotAllowed(name, in, key string) *Validation { + msg := fmt.Sprintf(unallowedProperty, name, key, in) + if in == "" { + msg = fmt.Sprintf(unallowedPropertyNoIn, name, key) + } + return &Validation{ + code: UnallowedPropertyCode, + Name: name, + In: in, + Value: key, + message: msg, + } +} + +// TooFewProperties an error for an object with too few properties +func TooFewProperties(name, in string, minProperties, size int64) *Validation { + msg := fmt.Sprintf(tooFewProperties, name, in, minProperties) + if in == "" { + msg = fmt.Sprintf(tooFewPropertiesNoIn, name, minProperties) + } + return &Validation{ + code: TooFewPropertiesCode, + Name: name, + In: in, + Value: size, + Valid: minProperties, + message: msg, + } +} + +// TooManyProperties an error for an object with too many properties +func TooManyProperties(name, in string, maxProperties, size int64) *Validation { + msg := fmt.Sprintf(tooManyProperties, name, in, maxProperties) + if in == "" { + msg = fmt.Sprintf(tooManyPropertiesNoIn, name, maxProperties) + } + return &Validation{ + code: TooManyPropertiesCode, + Name: name, + In: in, + Value: size, + Valid: maxProperties, + message: msg, + } +} + +// AdditionalItemsNotAllowed an error for invalid additional items +func AdditionalItemsNotAllowed(name, in string) *Validation { + msg := fmt.Sprintf(noAdditionalItems, name, in) + if in == "" { + msg = fmt.Sprintf(noAdditionalItemsNoIn, name) + } + return &Validation{ + code: NoAdditionalItemsCode, + Name: name, + In: in, + message: msg, + } +} + +// InvalidCollectionFormat another flavor of invalid type error +func InvalidCollectionFormat(name, in, format string) *Validation { + return &Validation{ + code: InvalidTypeCode, + Name: name, + In: in, + Value: format, + message: fmt.Sprintf("the collection format %q is not supported for the %s param %q", format, in, name), + } +} + +// InvalidTypeName an error for when the type is invalid +func InvalidTypeName(typeName string) *Validation { + return &Validation{ + code: InvalidTypeCode, + Value: typeName, + message: fmt.Sprintf(invalidType, typeName), + } +} + +// InvalidType creates an error for when the type is invalid +func InvalidType(name, in, typeName string, value interface{}) *Validation { + var message string + + if in != "" { + switch value.(type) { + case string: + message = fmt.Sprintf(typeFailWithData, name, in, typeName, value) + case error: + message = fmt.Sprintf(typeFailWithError, name, in, typeName, value) + default: + message = fmt.Sprintf(typeFail, name, in, typeName) + } + } else { + switch value.(type) { + case string: + message = fmt.Sprintf(typeFailWithDataNoIn, name, typeName, value) + case error: + message = fmt.Sprintf(typeFailWithErrorNoIn, name, typeName, value) + default: + message = fmt.Sprintf(typeFailNoIn, name, typeName) + } + } + + return &Validation{ + code: InvalidTypeCode, + Name: name, + In: in, + Value: value, + message: message, + } + +} + +// DuplicateItems error for when an array contains duplicates +func DuplicateItems(name, in string) *Validation { + msg := fmt.Sprintf(uniqueFail, name, in) + if in == "" { + msg = fmt.Sprintf(uniqueFailNoIn, name) + } + return &Validation{ + code: UniqueFailCode, + Name: name, + In: in, + message: msg, + } +} + +// TooManyItems error for when an array contains too many items +func TooManyItems(name, in string, max int64, value interface{}) *Validation { + msg := fmt.Sprintf(maxItemsFail, name, in, max) + if in == "" { + msg = fmt.Sprintf(maxItemsFailNoIn, name, max) + } + + return &Validation{ + code: MaxItemsFailCode, + Name: name, + In: in, + Value: value, + Valid: max, + message: msg, + } +} + +// TooFewItems error for when an array contains too few items +func TooFewItems(name, in string, min int64, value interface{}) *Validation { + msg := fmt.Sprintf(minItemsFail, name, in, min) + if in == "" { + msg = fmt.Sprintf(minItemsFailNoIn, name, min) + } + return &Validation{ + code: MinItemsFailCode, + Name: name, + In: in, + Value: value, + Valid: min, + message: msg, + } +} + +// ExceedsMaximumInt error for when maxinum validation fails +func ExceedsMaximumInt(name, in string, max int64, exclusive bool, value interface{}) *Validation { + var message string + if in == "" { + m := maxIncFailNoIn + if exclusive { + m = maxExcFailNoIn + } + message = fmt.Sprintf(m, name, max) + } else { + m := maxIncFail + if exclusive { + m = maxExcFail + } + message = fmt.Sprintf(m, name, in, max) + } + return &Validation{ + code: MaxFailCode, + Name: name, + In: in, + Value: value, + message: message, + } +} + +// ExceedsMaximumUint error for when maxinum validation fails +func ExceedsMaximumUint(name, in string, max uint64, exclusive bool, value interface{}) *Validation { + var message string + if in == "" { + m := maxIncFailNoIn + if exclusive { + m = maxExcFailNoIn + } + message = fmt.Sprintf(m, name, max) + } else { + m := maxIncFail + if exclusive { + m = maxExcFail + } + message = fmt.Sprintf(m, name, in, max) + } + return &Validation{ + code: MaxFailCode, + Name: name, + In: in, + Value: value, + message: message, + } +} + +// ExceedsMaximum error for when maxinum validation fails +func ExceedsMaximum(name, in string, max float64, exclusive bool, value interface{}) *Validation { + var message string + if in == "" { + m := maxIncFailNoIn + if exclusive { + m = maxExcFailNoIn + } + message = fmt.Sprintf(m, name, max) + } else { + m := maxIncFail + if exclusive { + m = maxExcFail + } + message = fmt.Sprintf(m, name, in, max) + } + return &Validation{ + code: MaxFailCode, + Name: name, + In: in, + Value: value, + message: message, + } +} + +// ExceedsMinimumInt error for when maxinum validation fails +func ExceedsMinimumInt(name, in string, min int64, exclusive bool, value interface{}) *Validation { + var message string + if in == "" { + m := minIncFailNoIn + if exclusive { + m = minExcFailNoIn + } + message = fmt.Sprintf(m, name, min) + } else { + m := minIncFail + if exclusive { + m = minExcFail + } + message = fmt.Sprintf(m, name, in, min) + } + return &Validation{ + code: MinFailCode, + Name: name, + In: in, + Value: value, + message: message, + } +} + +// ExceedsMinimumUint error for when maxinum validation fails +func ExceedsMinimumUint(name, in string, min uint64, exclusive bool, value interface{}) *Validation { + var message string + if in == "" { + m := minIncFailNoIn + if exclusive { + m = minExcFailNoIn + } + message = fmt.Sprintf(m, name, min) + } else { + m := minIncFail + if exclusive { + m = minExcFail + } + message = fmt.Sprintf(m, name, in, min) + } + return &Validation{ + code: MinFailCode, + Name: name, + In: in, + Value: value, + message: message, + } +} + +// ExceedsMinimum error for when maxinum validation fails +func ExceedsMinimum(name, in string, min float64, exclusive bool, value interface{}) *Validation { + var message string + if in == "" { + m := minIncFailNoIn + if exclusive { + m = minExcFailNoIn + } + message = fmt.Sprintf(m, name, min) + } else { + m := minIncFail + if exclusive { + m = minExcFail + } + message = fmt.Sprintf(m, name, in, min) + } + return &Validation{ + code: MinFailCode, + Name: name, + In: in, + Value: value, + message: message, + } +} + +// NotMultipleOf error for when multiple of validation fails +func NotMultipleOf(name, in string, multiple, value interface{}) *Validation { + var msg string + if in == "" { + msg = fmt.Sprintf(multipleOfFailNoIn, name, multiple) + } else { + msg = fmt.Sprintf(multipleOfFail, name, in, multiple) + } + return &Validation{ + code: MultipleOfFailCode, + Name: name, + In: in, + Value: value, + message: msg, + } +} + +// EnumFail error for when an enum validation fails +func EnumFail(name, in string, value interface{}, values []interface{}) *Validation { + var msg string + if in == "" { + msg = fmt.Sprintf(enumFailNoIn, name, values) + } else { + msg = fmt.Sprintf(enumFail, name, in, values) + } + + return &Validation{ + code: EnumFailCode, + Name: name, + In: in, + Value: value, + Values: values, + message: msg, + } +} + +// Required error for when a value is missing +func Required(name, in string) *Validation { + var msg string + if in == "" { + msg = fmt.Sprintf(requiredFailNoIn, name) + } else { + msg = fmt.Sprintf(requiredFail, name, in) + } + return &Validation{ + code: RequiredFailCode, + Name: name, + In: in, + message: msg, + } +} + +// TooLong error for when a string is too long +func TooLong(name, in string, max int64, value interface{}) *Validation { + var msg string + if in == "" { + msg = fmt.Sprintf(tooLongMessageNoIn, name, max) + } else { + msg = fmt.Sprintf(tooLongMessage, name, in, max) + } + return &Validation{ + code: TooLongFailCode, + Name: name, + In: in, + Value: value, + Valid: max, + message: msg, + } +} + +// TooShort error for when a string is too short +func TooShort(name, in string, min int64, value interface{}) *Validation { + var msg string + if in == "" { + msg = fmt.Sprintf(tooShortMessageNoIn, name, min) + } else { + msg = fmt.Sprintf(tooShortMessage, name, in, min) + } + + return &Validation{ + code: TooShortFailCode, + Name: name, + In: in, + Value: value, + Valid: min, + message: msg, + } +} + +// FailedPattern error for when a string fails a regex pattern match +// the pattern that is returned is the ECMA syntax version of the pattern not the golang version. +func FailedPattern(name, in, pattern string, value interface{}) *Validation { + var msg string + if in == "" { + msg = fmt.Sprintf(patternFailNoIn, name, pattern) + } else { + msg = fmt.Sprintf(patternFail, name, in, pattern) + } + + return &Validation{ + code: PatternFailCode, + Name: name, + In: in, + Value: value, + message: msg, + } +} + +// MultipleOfMustBePositive error for when a +// multipleOf factor is negative +func MultipleOfMustBePositive(name, in string, factor interface{}) *Validation { + return &Validation{ + code: MultipleOfMustBePositiveCode, + Name: name, + In: in, + Value: factor, + message: fmt.Sprintf(multipleOfMustBePositive, name, factor), + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go index 9a2556306a..05310c46b3 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go @@ -43,6 +43,9 @@ type Header struct { // MarshalJSON marshal this to JSON func (h Header) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(h) + } b1, err := json.Marshal(h.CommonValidations) if err != nil { return nil, err @@ -62,6 +65,20 @@ func (h Header) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3, b4), nil } +func (h Header) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + CommonValidations commonValidationsOmitZero `json:",inline"` + SimpleSchema simpleSchemaOmitZero `json:",inline"` + Extensions + HeaderProps + } + x.CommonValidations = commonValidationsOmitZero(h.CommonValidations) + x.SimpleSchema = simpleSchemaOmitZero(h.SimpleSchema) + x.Extensions = internal.SanitizeExtensions(h.Extensions) + x.HeaderProps = h.HeaderProps + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON unmarshals this header from JSON func (h *Header) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { @@ -94,12 +111,8 @@ func (h *Header) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Dec h.CommonValidations = x.CommonValidations h.SimpleSchema = x.SimpleSchema - h.Extensions = x.Extensions + h.Extensions = internal.SanitizeExtensions(x.Extensions) h.HeaderProps = x.HeaderProps - h.Extensions.sanitize() - if len(h.Extensions) == 0 { - h.Extensions = nil - } return nil } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go index 395ececae8..d667b705be 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go @@ -89,17 +89,9 @@ func (e Extensions) GetObject(key string, out interface{}) error { return nil } -func (e Extensions) sanitize() { - for k := range e { - if !isExtensionKey(k) { - delete(e, k) - } - } -} - func (e Extensions) sanitizeWithExtra() (extra map[string]any) { for k, v := range e { - if !isExtensionKey(k) { + if !internal.IsExtensionKey(k) { if extra == nil { extra = make(map[string]any) } @@ -110,10 +102,6 @@ func (e Extensions) sanitizeWithExtra() (extra map[string]any) { return extra } -func isExtensionKey(k string) bool { - return len(k) > 1 && (k[0] == 'x' || k[0] == 'X') && k[1] == '-' -} - // VendorExtensible composition block. type VendorExtensible struct { Extensions Extensions @@ -181,6 +169,9 @@ type Info struct { // MarshalJSON marshal this to JSON func (i Info) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(i) + } b1, err := json.Marshal(i.InfoProps) if err != nil { return nil, err @@ -192,6 +183,16 @@ func (i Info) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } +func (i Info) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Extensions + InfoProps + } + x.Extensions = i.Extensions + x.InfoProps = i.InfoProps + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON marshal this from JSON func (i *Info) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { @@ -212,11 +213,7 @@ func (i *Info) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decod if err := opts.UnmarshalNext(dec, &x); err != nil { return err } - x.Extensions.sanitize() - if len(x.Extensions) == 0 { - x.Extensions = nil - } - i.VendorExtensible.Extensions = x.Extensions + i.Extensions = internal.SanitizeExtensions(x.Extensions) i.InfoProps = x.InfoProps return nil } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go index 374f90d28d..4132467d24 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go @@ -37,6 +37,18 @@ type SimpleSchema struct { Example interface{} `json:"example,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type simpleSchemaOmitZero struct { + Type string `json:"type,omitempty"` + Nullable bool `json:"nullable,omitzero"` + Format string `json:"format,omitempty"` + Items *Items `json:"items,omitzero"` + CollectionFormat string `json:"collectionFormat,omitempty"` + Default interface{} `json:"default,omitempty"` + Example interface{} `json:"example,omitempty"` +} + // CommonValidations describe common JSON-schema validations type CommonValidations struct { Maximum *float64 `json:"maximum,omitempty"` @@ -53,6 +65,23 @@ type CommonValidations struct { Enum []interface{} `json:"enum,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type commonValidationsOmitZero struct { + Maximum *float64 `json:"maximum,omitempty"` + ExclusiveMaximum bool `json:"exclusiveMaximum,omitzero"` + Minimum *float64 `json:"minimum,omitempty"` + ExclusiveMinimum bool `json:"exclusiveMinimum,omitzero"` + MaxLength *int64 `json:"maxLength,omitempty"` + MinLength *int64 `json:"minLength,omitempty"` + Pattern string `json:"pattern,omitempty"` + MaxItems *int64 `json:"maxItems,omitempty"` + MinItems *int64 `json:"minItems,omitempty"` + UniqueItems bool `json:"uniqueItems,omitzero"` + MultipleOf *float64 `json:"multipleOf,omitempty"` + Enum []interface{} `json:"enum,omitempty"` +} + // Items a limited subset of JSON-Schema's items object. // It is used by parameter definitions that are not located in "body". // @@ -105,18 +134,18 @@ func (i *Items) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco if err := i.Refable.Ref.fromMap(x.Extensions); err != nil { return err } - x.Extensions.sanitize() - if len(x.Extensions) == 0 { - x.Extensions = nil - } + i.CommonValidations = x.CommonValidations i.SimpleSchema = x.SimpleSchema - i.VendorExtensible.Extensions = x.Extensions + i.Extensions = internal.SanitizeExtensions(x.Extensions) return nil } // MarshalJSON converts this items object to JSON func (i Items) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(i) + } b1, err := json.Marshal(i.CommonValidations) if err != nil { return nil, err @@ -135,3 +164,17 @@ func (i Items) MarshalJSON() ([]byte, error) { } return swag.ConcatJSON(b4, b3, b1, b2), nil } + +func (i Items) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + CommonValidations commonValidationsOmitZero `json:",inline"` + SimpleSchema simpleSchemaOmitZero `json:",inline"` + Ref string `json:"$ref,omitempty"` + Extensions + } + x.CommonValidations = commonValidationsOmitZero(i.CommonValidations) + x.SimpleSchema = simpleSchemaOmitZero(i.SimpleSchema) + x.Ref = i.Refable.Ref.String() + x.Extensions = internal.SanitizeExtensions(i.Extensions) + return opts.MarshalNext(enc, x) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go index 923769ae08..63eed34601 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go @@ -42,6 +42,23 @@ type OperationProps struct { Responses *Responses `json:"responses,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type operationPropsOmitZero struct { + Description string `json:"description,omitempty"` + Consumes []string `json:"consumes,omitempty"` + Produces []string `json:"produces,omitempty"` + Schemes []string `json:"schemes,omitempty"` + Tags []string `json:"tags,omitempty"` + Summary string `json:"summary,omitempty"` + ExternalDocs *ExternalDocumentation `json:"externalDocs,omitzero"` + ID string `json:"operationId,omitempty"` + Deprecated bool `json:"deprecated,omitempty,omitzero"` + Security []map[string][]string `json:"security,omitempty"` + Parameters []Parameter `json:"parameters,omitempty"` + Responses *Responses `json:"responses,omitzero"` +} + // MarshalJSON takes care of serializing operation properties to JSON // // We use a custom marhaller here to handle a special cases related to @@ -96,17 +113,16 @@ func (o *Operation) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2. if err := opts.UnmarshalNext(dec, &x); err != nil { return err } - x.Extensions.sanitize() - if len(x.Extensions) == 0 { - x.Extensions = nil - } - o.VendorExtensible.Extensions = x.Extensions + o.Extensions = internal.SanitizeExtensions(x.Extensions) o.OperationProps = OperationProps(x.OperationPropsNoMethods) return nil } // MarshalJSON converts this items object to JSON func (o Operation) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(o) + } b1, err := json.Marshal(o.OperationProps) if err != nil { return nil, err @@ -118,3 +134,13 @@ func (o Operation) MarshalJSON() ([]byte, error) { concated := swag.ConcatJSON(b1, b2) return concated, nil } + +func (o Operation) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Extensions + OperationProps operationPropsOmitZero `json:",inline"` + } + x.Extensions = internal.SanitizeExtensions(o.Extensions) + x.OperationProps = operationPropsOmitZero(o.OperationProps) + return opts.MarshalNext(enc, x) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go index 7cb229ac13..53d1e0aa94 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go @@ -36,6 +36,17 @@ type ParamProps struct { AllowEmptyValue bool `json:"allowEmptyValue,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type paramPropsOmitZero struct { + Description string `json:"description,omitempty"` + Name string `json:"name,omitempty"` + In string `json:"in,omitempty"` + Required bool `json:"required,omitzero"` + Schema *Schema `json:"schema,omitzero"` + AllowEmptyValue bool `json:"allowEmptyValue,omitzero"` +} + // Parameter a unique parameter is defined by a combination of a [name](#parameterName) and [location](#parameterIn). // // There are five possible parameter types. @@ -109,19 +120,18 @@ func (p *Parameter) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2. if err := p.Refable.Ref.fromMap(x.Extensions); err != nil { return err } - x.Extensions.sanitize() - if len(x.Extensions) == 0 { - x.Extensions = nil - } p.CommonValidations = x.CommonValidations p.SimpleSchema = x.SimpleSchema - p.VendorExtensible.Extensions = x.Extensions + p.Extensions = internal.SanitizeExtensions(x.Extensions) p.ParamProps = x.ParamProps return nil } // MarshalJSON converts this items object to JSON func (p Parameter) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(p) + } b1, err := json.Marshal(p.CommonValidations) if err != nil { return nil, err @@ -144,3 +154,19 @@ func (p Parameter) MarshalJSON() ([]byte, error) { } return swag.ConcatJSON(b3, b1, b2, b4, b5), nil } + +func (p Parameter) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + CommonValidations commonValidationsOmitZero `json:",inline"` + SimpleSchema simpleSchemaOmitZero `json:",inline"` + ParamProps paramPropsOmitZero `json:",inline"` + Ref string `json:"$ref,omitempty"` + Extensions + } + x.CommonValidations = commonValidationsOmitZero(p.CommonValidations) + x.SimpleSchema = simpleSchemaOmitZero(p.SimpleSchema) + x.Extensions = internal.SanitizeExtensions(p.Extensions) + x.ParamProps = paramPropsOmitZero(p.ParamProps) + x.Ref = p.Refable.Ref.String() + return opts.MarshalNext(enc, x) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go index 03741fcfb5..1d1588cb92 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go @@ -70,24 +70,20 @@ func (p *PathItem) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.D if err := opts.UnmarshalNext(dec, &x); err != nil { return err } - - p.Extensions = x.Extensions - p.PathItemProps = x.PathItemProps - - if err := p.Refable.Ref.fromMap(p.Extensions); err != nil { + if err := p.Refable.Ref.fromMap(x.Extensions); err != nil { return err } - - p.Extensions.sanitize() - if len(p.Extensions) == 0 { - p.Extensions = nil - } + p.Extensions = internal.SanitizeExtensions(x.Extensions) + p.PathItemProps = x.PathItemProps return nil } // MarshalJSON converts this items object to JSON func (p PathItem) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(p) + } b3, err := json.Marshal(p.Refable) if err != nil { return nil, err @@ -103,3 +99,15 @@ func (p PathItem) MarshalJSON() ([]byte, error) { concated := swag.ConcatJSON(b3, b4, b5) return concated, nil } + +func (p PathItem) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Ref string `json:"$ref,omitempty"` + Extensions + PathItemProps + } + x.Ref = p.Refable.Ref.String() + x.Extensions = internal.SanitizeExtensions(p.Extensions) + x.PathItemProps = p.PathItemProps + return opts.MarshalNext(enc, x) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go index 7c63d440aa..18f6a9f429 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go @@ -92,7 +92,7 @@ func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco } switch k := tok.String(); { - case isExtensionKey(k): + case internal.IsExtensionKey(k): ext = nil if err := opts.UnmarshalNext(dec, &ext); err != nil { return err @@ -114,7 +114,9 @@ func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco p.Paths[k] = pi default: _, err := dec.ReadValue() // skip value - return err + if err != nil { + return err + } } } default: @@ -124,6 +126,9 @@ func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco // MarshalJSON converts this items object to JSON func (p Paths) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(p) + } b1, err := json.Marshal(p.VendorExtensible) if err != nil { return nil, err @@ -142,3 +147,18 @@ func (p Paths) MarshalJSON() ([]byte, error) { concated := swag.ConcatJSON(b1, b2) return concated, nil } + +func (p Paths) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + m := make(map[string]any, len(p.Extensions)+len(p.Paths)) + for k, v := range p.Extensions { + if internal.IsExtensionKey(k) { + m[k] = v + } + } + for k, v := range p.Paths { + if strings.HasPrefix(k, "/") { + m[k] = v + } + } + return opts.MarshalNext(enc, m) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/ref.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/ref.go index 1405bfd8ee..775b3b0c36 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/ref.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/ref.go @@ -21,6 +21,8 @@ import ( "path/filepath" "github.com/go-openapi/jsonreference" + + "k8s.io/kube-openapi/pkg/internal" ) // Refable is a struct for things that accept a $ref property @@ -149,19 +151,5 @@ func (r *Ref) UnmarshalJSON(d []byte) error { } func (r *Ref) fromMap(v map[string]interface{}) error { - if v == nil { - return nil - } - - if vv, ok := v["$ref"]; ok { - if str, ok := vv.(string); ok { - ref, err := jsonreference.New(str) - if err != nil { - return err - } - *r = Ref{Ref: ref} - } - } - - return nil + return internal.JSONRefFromMap(&r.Ref, v) } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go index f01364b75c..3ff1fe1322 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go @@ -30,6 +30,15 @@ type ResponseProps struct { Examples map[string]interface{} `json:"examples,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type responsePropsOmitZero struct { + Description string `json:"description,omitempty"` + Schema *Schema `json:"schema,omitzero"` + Headers map[string]Header `json:"headers,omitempty"` + Examples map[string]interface{} `json:"examples,omitempty"` +} + // Response describes a single response from an API Operation. // // For more information: http://goo.gl/8us55a#responseObject @@ -68,23 +77,20 @@ func (r *Response) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.D return err } - r.Extensions = x.Extensions - r.ResponseProps = x.ResponseProps - - if err := r.Refable.Ref.fromMap(r.Extensions); err != nil { + if err := r.Refable.Ref.fromMap(x.Extensions); err != nil { return err } - - r.Extensions.sanitize() - if len(r.Extensions) == 0 { - r.Extensions = nil - } + r.Extensions = internal.SanitizeExtensions(x.Extensions) + r.ResponseProps = x.ResponseProps return nil } // MarshalJSON converts this items object to JSON func (r Response) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(r) + } b1, err := json.Marshal(r.ResponseProps) if err != nil { return nil, err @@ -100,6 +106,18 @@ func (r Response) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3), nil } +func (r Response) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Ref string `json:"$ref,omitempty"` + Extensions + ResponseProps responsePropsOmitZero `json:",inline"` + } + x.Ref = r.Refable.Ref.String() + x.Extensions = internal.SanitizeExtensions(r.Extensions) + x.ResponseProps = responsePropsOmitZero(r.ResponseProps) + return opts.MarshalNext(enc, x) +} + // NewResponse creates a new response instance func NewResponse() *Response { return new(Response) diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go index c3fa68191d..d9ad760a43 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go @@ -63,6 +63,9 @@ func (r *Responses) UnmarshalJSON(data []byte) error { // MarshalJSON converts this items object to JSON func (r Responses) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(r) + } b1, err := json.Marshal(r.ResponsesProps) if err != nil { return nil, err @@ -75,6 +78,25 @@ func (r Responses) MarshalJSON() ([]byte, error) { return concated, nil } +func (r Responses) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + type ArbitraryKeys map[string]interface{} + var x struct { + ArbitraryKeys + Default *Response `json:"default,omitempty"` + } + x.ArbitraryKeys = make(map[string]any, len(r.Extensions)+len(r.StatusCodeResponses)) + for k, v := range r.Extensions { + if internal.IsExtensionKey(k) { + x.ArbitraryKeys[k] = v + } + } + for k, v := range r.StatusCodeResponses { + x.ArbitraryKeys[strconv.Itoa(k)] = v + } + x.Default = r.Default + return opts.MarshalNext(enc, x) +} + // ResponsesProps describes all responses for an operation. // It tells what is the default response and maps all responses with a // HTTP status code. @@ -148,7 +170,7 @@ func (r *Responses) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2. return nil } switch k := tok.String(); { - case isExtensionKey(k): + case internal.IsExtensionKey(k): ext = nil if err := opts.UnmarshalNext(dec, &ext); err != nil { return err diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go index 9add0c163d..dfbb2e05cb 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go @@ -196,6 +196,46 @@ type SchemaProps struct { Definitions Definitions `json:"definitions,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type schemaPropsOmitZero struct { + ID string `json:"id,omitempty"` + Ref Ref `json:"-"` + Schema SchemaURL `json:"-"` + Description string `json:"description,omitempty"` + Type StringOrArray `json:"type,omitzero"` + Nullable bool `json:"nullable,omitzero"` + Format string `json:"format,omitempty"` + Title string `json:"title,omitempty"` + Default interface{} `json:"default,omitzero"` + Maximum *float64 `json:"maximum,omitempty"` + ExclusiveMaximum bool `json:"exclusiveMaximum,omitzero"` + Minimum *float64 `json:"minimum,omitempty"` + ExclusiveMinimum bool `json:"exclusiveMinimum,omitzero"` + MaxLength *int64 `json:"maxLength,omitempty"` + MinLength *int64 `json:"minLength,omitempty"` + Pattern string `json:"pattern,omitempty"` + MaxItems *int64 `json:"maxItems,omitempty"` + MinItems *int64 `json:"minItems,omitempty"` + UniqueItems bool `json:"uniqueItems,omitzero"` + MultipleOf *float64 `json:"multipleOf,omitempty"` + Enum []interface{} `json:"enum,omitempty"` + MaxProperties *int64 `json:"maxProperties,omitempty"` + MinProperties *int64 `json:"minProperties,omitempty"` + Required []string `json:"required,omitempty"` + Items *SchemaOrArray `json:"items,omitzero"` + AllOf []Schema `json:"allOf,omitempty"` + OneOf []Schema `json:"oneOf,omitempty"` + AnyOf []Schema `json:"anyOf,omitempty"` + Not *Schema `json:"not,omitzero"` + Properties map[string]Schema `json:"properties,omitempty"` + AdditionalProperties *SchemaOrBool `json:"additionalProperties,omitzero"` + PatternProperties map[string]Schema `json:"patternProperties,omitempty"` + Dependencies Dependencies `json:"dependencies,omitempty"` + AdditionalItems *SchemaOrBool `json:"additionalItems,omitzero"` + Definitions Definitions `json:"definitions,omitempty"` +} + // SwaggerSchemaProps are additional properties supported by swagger schemas, but not JSON-schema (draft 4) type SwaggerSchemaProps struct { Discriminator string `json:"discriminator,omitempty"` @@ -204,6 +244,15 @@ type SwaggerSchemaProps struct { Example interface{} `json:"example,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type swaggerSchemaPropsOmitZero struct { + Discriminator string `json:"discriminator,omitempty"` + ReadOnly bool `json:"readOnly,omitzero"` + ExternalDocs *ExternalDocumentation `json:"externalDocs,omitzero"` + Example interface{} `json:"example,omitempty"` +} + // Schema the schema object allows the definition of input and output data types. // These types can be objects, but also primitives and arrays. // This object is based on the [JSON Schema Specification Draft 4](http://json-schema.org/) @@ -434,6 +483,9 @@ func (s *Schema) WithExternalDocs(description, url string) *Schema { // MarshalJSON marshal this to JSON func (s Schema) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } b1, err := json.Marshal(s.SchemaProps) if err != nil { return nil, fmt.Errorf("schema props %v", err) @@ -465,6 +517,31 @@ func (s Schema) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3, b4, b5, b6), nil } +func (s Schema) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + type ArbitraryKeys map[string]interface{} + var x struct { + ArbitraryKeys + SchemaProps schemaPropsOmitZero `json:",inline"` + SwaggerSchemaProps swaggerSchemaPropsOmitZero `json:",inline"` + Schema string `json:"$schema,omitempty"` + Ref string `json:"$ref,omitempty"` + } + x.ArbitraryKeys = make(map[string]any, len(s.Extensions)+len(s.ExtraProps)) + for k, v := range s.Extensions { + if internal.IsExtensionKey(k) { + x.ArbitraryKeys[k] = v + } + } + for k, v := range s.ExtraProps { + x.ArbitraryKeys[k] = v + } + x.SchemaProps = schemaPropsOmitZero(s.SchemaProps) + x.SwaggerSchemaProps = swaggerSchemaPropsOmitZero(s.SwaggerSchemaProps) + x.Ref = s.Ref.String() + x.Schema = string(s.Schema) + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON marshal this from JSON func (s *Schema) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { @@ -547,7 +624,7 @@ func (s *Schema) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Dec } s.ExtraProps = x.Extensions.sanitizeWithExtra() - s.VendorExtensible.Extensions = x.Extensions + s.Extensions = internal.SanitizeExtensions(x.Extensions) s.SchemaProps = x.SchemaProps s.SwaggerSchemaProps = x.SwaggerSchemaProps return nil diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go index 34723fb715..e2b7da14cf 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go @@ -18,6 +18,7 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" ) @@ -45,6 +46,9 @@ type SecurityScheme struct { // MarshalJSON marshal this to JSON func (s SecurityScheme) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } b1, err := json.Marshal(s.SecuritySchemeProps) if err != nil { return nil, err @@ -56,6 +60,16 @@ func (s SecurityScheme) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } +func (s SecurityScheme) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Extensions + SecuritySchemeProps + } + x.Extensions = internal.SanitizeExtensions(s.Extensions) + x.SecuritySchemeProps = s.SecuritySchemeProps + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON marshal this from JSON func (s *SecurityScheme) UnmarshalJSON(data []byte) error { if err := json.Unmarshal(data, &s.SecuritySchemeProps); err != nil { @@ -72,11 +86,7 @@ func (s *SecurityScheme) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *js if err := opts.UnmarshalNext(dec, &x); err != nil { return err } - x.Extensions.sanitize() - if len(x.Extensions) == 0 { - x.Extensions = nil - } - s.VendorExtensible.Extensions = x.Extensions + s.Extensions = internal.SanitizeExtensions(x.Extensions) s.SecuritySchemeProps = x.SecuritySchemeProps return nil } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go index f6cb7da3f2..c8f3beaa35 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go @@ -35,6 +35,9 @@ type Swagger struct { // MarshalJSON marshals this swagger structure to json func (s Swagger) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } b1, err := json.Marshal(s.SwaggerProps) if err != nil { return nil, err @@ -46,12 +49,22 @@ func (s Swagger) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } +// MarshalJSON marshals this swagger structure to json +func (s Swagger) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Extensions + SwaggerProps + } + x.Extensions = internal.SanitizeExtensions(s.Extensions) + x.SwaggerProps = s.SwaggerProps + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON unmarshals a swagger spec from json func (s *Swagger) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { return jsonv2.Unmarshal(data, s) } - var sw Swagger if err := json.Unmarshal(data, &sw.SwaggerProps); err != nil { return err @@ -75,15 +88,8 @@ func (s *Swagger) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.De if err := opts.UnmarshalNext(dec, &x); err != nil { return err } - - s.Extensions = x.Extensions + s.Extensions = internal.SanitizeExtensions(x.Extensions) s.SwaggerProps = x.SwaggerProps - - s.Extensions.sanitize() - if len(s.Extensions) == 0 { - s.Extensions = nil - } - return nil } @@ -126,6 +132,9 @@ var jsFalse = []byte("false") // MarshalJSON convert this object to JSON func (s SchemaOrBool) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } if s.Schema != nil { return json.Marshal(s.Schema) } @@ -136,6 +145,18 @@ func (s SchemaOrBool) MarshalJSON() ([]byte, error) { return jsTrue, nil } +// MarshalJSON convert this object to JSON +func (s SchemaOrBool) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + if s.Schema != nil { + return opts.MarshalNext(enc, s.Schema) + } + + if s.Schema == nil && !s.Allows { + return enc.WriteToken(jsonv2.False) + } + return enc.WriteToken(jsonv2.True) +} + // UnmarshalJSON converts this bool or schema object from a JSON structure func (s *SchemaOrBool) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { @@ -143,15 +164,15 @@ func (s *SchemaOrBool) UnmarshalJSON(data []byte) error { } var nw SchemaOrBool - if len(data) >= 4 { - if data[0] == '{' { - var sch Schema - if err := json.Unmarshal(data, &sch); err != nil { - return err - } - nw.Schema = &sch + if len(data) > 0 && data[0] == '{' { + var sch Schema + if err := json.Unmarshal(data, &sch); err != nil { + return err } - nw.Allows = !(data[0] == 'f' && data[1] == 'a' && data[2] == 'l' && data[3] == 's' && data[4] == 'e') + nw.Schema = &sch + nw.Allows = true + } else { + json.Unmarshal(data, &nw.Allows) } *s = nw return nil @@ -185,6 +206,9 @@ type SchemaOrStringArray struct { // MarshalJSON converts this schema object or array into JSON structure func (s SchemaOrStringArray) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } if len(s.Property) > 0 { return json.Marshal(s.Property) } @@ -194,6 +218,17 @@ func (s SchemaOrStringArray) MarshalJSON() ([]byte, error) { return []byte("null"), nil } +// MarshalJSON converts this schema object or array into JSON structure +func (s SchemaOrStringArray) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + if len(s.Property) > 0 { + return opts.MarshalNext(enc, s.Property) + } + if s.Schema != nil { + return opts.MarshalNext(enc, s.Schema) + } + return enc.WriteToken(jsonv2.Null) +} + // UnmarshalJSON converts this schema object or array from a JSON structure func (s *SchemaOrStringArray) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { @@ -347,12 +382,23 @@ func (s *SchemaOrArray) ContainsType(name string) bool { // MarshalJSON converts this schema object or array into JSON structure func (s SchemaOrArray) MarshalJSON() ([]byte, error) { - if len(s.Schemas) > 0 { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } + if s.Schemas != nil { return json.Marshal(s.Schemas) } return json.Marshal(s.Schema) } +// MarshalJSON converts this schema object or array into JSON structure +func (s SchemaOrArray) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + if s.Schemas != nil { + return opts.MarshalNext(enc, s.Schemas) + } + return opts.MarshalNext(enc, s.Schema) +} + // UnmarshalJSON converts this schema object or array from a JSON structure func (s *SchemaOrArray) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go index 69e93b60bd..d105d52ca4 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go @@ -41,6 +41,9 @@ type Tag struct { // MarshalJSON marshal this to JSON func (t Tag) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(t) + } b1, err := json.Marshal(t.TagProps) if err != nil { return nil, err @@ -52,6 +55,16 @@ func (t Tag) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } +func (t Tag) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Extensions + TagProps + } + x.Extensions = internal.SanitizeExtensions(t.Extensions) + x.TagProps = t.TagProps + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON marshal this from JSON func (t *Tag) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { @@ -72,11 +85,7 @@ func (t *Tag) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decode if err := opts.UnmarshalNext(dec, &x); err != nil { return err } - x.Extensions.sanitize() - if len(x.Extensions) == 0 { - x.Extensions = nil - } - t.VendorExtensible.Extensions = x.Extensions + t.Extensions = internal.SanitizeExtensions(x.Extensions) t.TagProps = x.TagProps return nil } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/.gitignore b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/.gitignore new file mode 100644 index 0000000000..dd91ed6a04 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/.gitignore @@ -0,0 +1,2 @@ +secrets.yml +coverage.out diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/LICENSE b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/LICENSE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/bson.go b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/bson.go new file mode 100644 index 0000000000..0b6380c8af --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/bson.go @@ -0,0 +1,103 @@ +// Copyright 2015 go-swagger maintainers +// +// 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 strfmt + +import ( + bsonprim "k8s.io/kube-openapi/pkg/validation/strfmt/bson" +) + +func init() { + var id ObjectId + // register this format in the default registry + Default.Add("bsonobjectid", &id, IsBSONObjectID) +} + +// IsBSONObjectID returns true when the string is a valid BSON.ObjectId +func IsBSONObjectID(str string) bool { + _, err := bsonprim.ObjectIDFromHex(str) + return err == nil +} + +// ObjectId represents a BSON object ID (alias to go.mongodb.org/mongo-driver/bson/primitive.ObjectID) +// +// swagger:strfmt bsonobjectid +type ObjectId bsonprim.ObjectID + +// NewObjectId creates a ObjectId from a Hex String +func NewObjectId(hex string) ObjectId { + oid, err := bsonprim.ObjectIDFromHex(hex) + if err != nil { + panic(err) + } + return ObjectId(oid) +} + +// MarshalText turns this instance into text +func (id ObjectId) MarshalText() ([]byte, error) { + oid := bsonprim.ObjectID(id) + if oid == bsonprim.NilObjectID { + return nil, nil + } + return []byte(oid.Hex()), nil +} + +// UnmarshalText hydrates this instance from text +func (id *ObjectId) UnmarshalText(data []byte) error { // validation is performed later on + if len(data) == 0 { + *id = ObjectId(bsonprim.NilObjectID) + return nil + } + oidstr := string(data) + oid, err := bsonprim.ObjectIDFromHex(oidstr) + if err != nil { + return err + } + *id = ObjectId(oid) + return nil +} + +func (id ObjectId) String() string { + return bsonprim.ObjectID(id).String() +} + +// MarshalJSON returns the ObjectId as JSON +func (id ObjectId) MarshalJSON() ([]byte, error) { + return bsonprim.ObjectID(id).MarshalJSON() +} + +// UnmarshalJSON sets the ObjectId from JSON +func (id *ObjectId) UnmarshalJSON(data []byte) error { + var obj bsonprim.ObjectID + if err := obj.UnmarshalJSON(data); err != nil { + return err + } + *id = ObjectId(obj) + return nil +} + +// DeepCopyInto copies the receiver and writes its value into out. +func (id *ObjectId) DeepCopyInto(out *ObjectId) { + *out = *id +} + +// DeepCopy copies the receiver into a new ObjectId. +func (id *ObjectId) DeepCopy() *ObjectId { + if id == nil { + return nil + } + out := new(ObjectId) + id.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/bson/objectid.go b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/bson/objectid.go new file mode 100644 index 0000000000..824534b288 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/bson/objectid.go @@ -0,0 +1,122 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 +// +// Based on gopkg.in/mgo.v2/bson by Gustavo Niemeyer +// See THIRD-PARTY-NOTICES for original license terms. + +package bson + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "errors" + "fmt" +) + +// ErrInvalidHex indicates that a hex string cannot be converted to an ObjectID. +var ErrInvalidHex = errors.New("the provided hex string is not a valid ObjectID") + +// ObjectID is the BSON ObjectID type. +type ObjectID [12]byte + +// NilObjectID is the zero value for ObjectID. +var NilObjectID ObjectID + +// Hex returns the hex encoding of the ObjectID as a string. +func (id ObjectID) Hex() string { + return hex.EncodeToString(id[:]) +} + +func (id ObjectID) String() string { + return fmt.Sprintf("ObjectID(%q)", id.Hex()) +} + +// IsZero returns true if id is the empty ObjectID. +func (id ObjectID) IsZero() bool { + return bytes.Equal(id[:], NilObjectID[:]) +} + +// ObjectIDFromHex creates a new ObjectID from a hex string. It returns an error if the hex string is not a +// valid ObjectID. +func ObjectIDFromHex(s string) (ObjectID, error) { + b, err := hex.DecodeString(s) + if err != nil { + return NilObjectID, err + } + + if len(b) != 12 { + return NilObjectID, ErrInvalidHex + } + + var oid [12]byte + copy(oid[:], b[:]) + + return oid, nil +} + +// MarshalJSON returns the ObjectID as a string +func (id ObjectID) MarshalJSON() ([]byte, error) { + return json.Marshal(id.Hex()) +} + +// UnmarshalJSON populates the byte slice with the ObjectID. If the byte slice is 24 bytes long, it +// will be populated with the hex representation of the ObjectID. If the byte slice is twelve bytes +// long, it will be populated with the BSON representation of the ObjectID. This method also accepts empty strings and +// decodes them as NilObjectID. For any other inputs, an error will be returned. +func (id *ObjectID) UnmarshalJSON(b []byte) error { + // Ignore "null" to keep parity with the standard library. Decoding a JSON null into a non-pointer ObjectID field + // will leave the field unchanged. For pointer values, encoding/json will set the pointer to nil and will not + // enter the UnmarshalJSON hook. + if string(b) == "null" { + return nil + } + + var err error + switch len(b) { + case 12: + copy(id[:], b) + default: + // Extended JSON + var res interface{} + err := json.Unmarshal(b, &res) + if err != nil { + return err + } + str, ok := res.(string) + if !ok { + m, ok := res.(map[string]interface{}) + if !ok { + return errors.New("not an extended JSON ObjectID") + } + oid, ok := m["$oid"] + if !ok { + return errors.New("not an extended JSON ObjectID") + } + str, ok = oid.(string) + if !ok { + return errors.New("not an extended JSON ObjectID") + } + } + + // An empty string is not a valid ObjectID, but we treat it as a special value that decodes as NilObjectID. + if len(str) == 0 { + copy(id[:], NilObjectID[:]) + return nil + } + + if len(str) != 24 { + return fmt.Errorf("cannot unmarshal into an ObjectID, the length must be 24 but it is %d", len(str)) + } + + _, err = hex.Decode(id[:], []byte(str)) + if err != nil { + return err + } + } + + return err +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/date.go b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/date.go new file mode 100644 index 0000000000..74ce5b6cb6 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/date.go @@ -0,0 +1,103 @@ +// Copyright 2015 go-swagger maintainers +// +// 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 strfmt + +import ( + "encoding/json" + "time" +) + +func init() { + d := Date{} + // register this format in the default registry + Default.Add("date", &d, IsDate) +} + +// IsDate returns true when the string is a valid date +func IsDate(str string) bool { + _, err := time.Parse(RFC3339FullDate, str) + return err == nil +} + +const ( + // RFC3339FullDate represents a full-date as specified by RFC3339 + // See: http://goo.gl/xXOvVd + RFC3339FullDate = "2006-01-02" +) + +// Date represents a date from the API +// +// swagger:strfmt date +type Date time.Time + +// String converts this date into a string +func (d Date) String() string { + return time.Time(d).Format(RFC3339FullDate) +} + +// UnmarshalText parses a text representation into a date type +func (d *Date) UnmarshalText(text []byte) error { + if len(text) == 0 { + return nil + } + dd, err := time.Parse(RFC3339FullDate, string(text)) + if err != nil { + return err + } + *d = Date(dd) + return nil +} + +// MarshalText serializes this date type to string +func (d Date) MarshalText() ([]byte, error) { + return []byte(d.String()), nil +} + +// MarshalJSON returns the Date as JSON +func (d Date) MarshalJSON() ([]byte, error) { + return json.Marshal(time.Time(d).Format(RFC3339FullDate)) +} + +// UnmarshalJSON sets the Date from JSON +func (d *Date) UnmarshalJSON(data []byte) error { + if string(data) == jsonNull { + return nil + } + var strdate string + if err := json.Unmarshal(data, &strdate); err != nil { + return err + } + tt, err := time.Parse(RFC3339FullDate, strdate) + if err != nil { + return err + } + *d = Date(tt) + return nil +} + +// DeepCopyInto copies the receiver and writes its value into out. +func (d *Date) DeepCopyInto(out *Date) { + *out = *d +} + +// DeepCopy copies the receiver into a new Date. +func (d *Date) DeepCopy() *Date { + if d == nil { + return nil + } + out := new(Date) + d.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/default.go b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/default.go new file mode 100644 index 0000000000..e85b0f1b46 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/default.go @@ -0,0 +1,1562 @@ +// Copyright 2015 go-swagger maintainers +// +// 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 strfmt + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "net/mail" + "regexp" + "strings" + + "github.com/asaskevich/govalidator" + + netutils "k8s.io/utils/net" +) + +const ( + // HostnamePattern http://json-schema.org/latest/json-schema-validation.html#anchor114 + // A string instance is valid against this attribute if it is a valid + // representation for an Internet host name, as defined by RFC 1034, section 3.1 [RFC1034]. + // http://tools.ietf.org/html/rfc1034#section-3.5 + // ::= any one of the ten digits 0 through 9 + // var digit = /[0-9]/; + // ::= any one of the 52 alphabetic characters A through Z in upper case and a through z in lower case + // var letter = /[a-zA-Z]/; + // ::= | + // var letDig = /[0-9a-zA-Z]/; + // ::= | "-" + // var letDigHyp = /[-0-9a-zA-Z]/; + // ::= | + // var ldhStr = /[-0-9a-zA-Z]+/; + //

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 diff --git a/charts/latest/azurefile-csi-driver/Chart.yaml b/charts/latest/azurefile-csi-driver/Chart.yaml index 57bdefbd1a..27ff7d757c 100644 --- a/charts/latest/azurefile-csi-driver/Chart.yaml +++ b/charts/latest/azurefile-csi-driver/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: v1.27.0 +appVersion: latest description: Azure File Container Storage Interface (CSI) Storage Plugin name: azurefile-csi-driver -version: v1.27.0 +version: v0.0.0 diff --git a/charts/latest/azurefile-csi-driver/values.yaml b/charts/latest/azurefile-csi-driver/values.yaml index ee40d1e5e7..486cec43d1 100644 --- a/charts/latest/azurefile-csi-driver/values.yaml +++ b/charts/latest/azurefile-csi-driver/values.yaml @@ -1,8 +1,8 @@ image: baseRepo: mcr.microsoft.com azurefile: - repository: /oss/kubernetes-csi/azurefile-csi - tag: v1.27.0 + repository: /k8s/csi/azurefile-csi + tag: latest pullPolicy: IfNotPresent csiProvisioner: repository: /oss/kubernetes-csi/csi-provisioner diff --git a/deploy/csi-azurefile-controller.yaml b/deploy/csi-azurefile-controller.yaml index f26f7c6387..682f934cbd 100644 --- a/deploy/csi-azurefile-controller.yaml +++ b/deploy/csi-azurefile-controller.yaml @@ -133,7 +133,7 @@ spec: cpu: 10m memory: 20Mi - name: azurefile - image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.27.0 + image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest imagePullPolicy: IfNotPresent args: - "--v=5" diff --git a/deploy/csi-azurefile-driver.yaml b/deploy/csi-azurefile-driver.yaml index 2de1e57937..55d31ed2d1 100644 --- a/deploy/csi-azurefile-driver.yaml +++ b/deploy/csi-azurefile-driver.yaml @@ -4,7 +4,7 @@ kind: CSIDriver metadata: name: file.csi.azure.com annotations: - csiDriver: v1.27.0 + csiDriver: latest snapshot: v5.0.1 spec: attachRequired: false diff --git a/deploy/csi-azurefile-node-windows.yaml b/deploy/csi-azurefile-node-windows.yaml index 306ecffb84..4319db7002 100644 --- a/deploy/csi-azurefile-node-windows.yaml +++ b/deploy/csi-azurefile-node-windows.yaml @@ -94,7 +94,7 @@ spec: cpu: 30m memory: 40Mi - name: azurefile - image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.27.0 + image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest imagePullPolicy: IfNotPresent args: - --v=5 diff --git a/deploy/csi-azurefile-node.yaml b/deploy/csi-azurefile-node.yaml index c95b95e0cc..881a516b6c 100644 --- a/deploy/csi-azurefile-node.yaml +++ b/deploy/csi-azurefile-node.yaml @@ -85,7 +85,7 @@ spec: cpu: 10m memory: 20Mi - name: azurefile - image: mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.27.0 + image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest imagePullPolicy: IfNotPresent args: - "--v=5" From de7ee02f60bca50e695279adf79b12ba9c666e3b Mon Sep 17 00:00:00 2001 From: Andy Zhang Date: Thu, 27 Apr 2023 17:29:29 +0800 Subject: [PATCH 069/109] chore: switch master branch version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 079346a416..f48c3c0bce 100755 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ GIT_COMMIT ?= $(shell git rev-parse HEAD) REGISTRY ?= andyzhangx REGISTRY_NAME ?= $(shell echo $(REGISTRY) | sed "s/.azurecr.io//g") IMAGE_NAME ?= azurefile-csi -IMAGE_VERSION ?= v1.27.0 +IMAGE_VERSION ?= v1.28.0 # Use a custom version for E2E tests if we are testing in CI ifdef CI ifndef PUBLISH From 856602bbebd466de9765cc205791b8d1d6a0ea14 Mon Sep 17 00:00:00 2001 From: Andy Zhang Date: Fri, 28 Apr 2023 11:59:01 +0800 Subject: [PATCH 070/109] Update csi-debug.md --- docs/csi-debug.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/csi-debug.md b/docs/csi-debug.md index d2d2ea333f..846e88f455 100644 --- a/docs/csi-debug.md +++ b/docs/csi-debug.md @@ -31,8 +31,9 @@ csi-azurefile-node-dr4s4 3/3 Running 0 7m4 - get pod description and logs ```console -kubectl describe pod csi-azurefile-node-cvgbs -n kube-system > csi-azurefile-node-description.log kubectl logs csi-azurefile-node-cvgbs -c azurefile -n kube-system > csi-azurefile-node.log +# only collect following logs if there is driver crash issue +kubectl describe pod csi-azurefile-node-cvgbs -n kube-system > csi-azurefile-node-description.log kubectl logs csi-azurefile-node-cvgbs -c node-driver-registrar -n kube-system > node-driver-registrar.log ``` From 8848b61928c798e83eea1043170bec12cac20dfb Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Sun, 30 Apr 2023 08:28:31 +0000 Subject: [PATCH 071/109] chore: upgrade csi sidecar container images --- charts/README.md | 10 +++++----- charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 11664 -> 11661 bytes .../latest/azurefile-csi-driver/values.yaml | 10 +++++----- deploy/csi-azurefile-controller.yaml | 8 ++++---- deploy/csi-azurefile-node-windows.yaml | 4 ++-- deploy/csi-azurefile-node.yaml | 4 ++-- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/charts/README.md b/charts/README.md index 0ab07ae04a..fcaa9fa46a 100644 --- a/charts/README.md +++ b/charts/README.md @@ -57,19 +57,19 @@ The following table lists the configurable parameters of the latest Azure File C | `image.azurefile.tag` | azurefile-csi-driver docker image tag | `` | | `image.azurefile.pullPolicy` | azurefile-csi-driver image pull policy | `IfNotPresent` | | `image.csiProvisioner.repository` | csi-provisioner docker image | `/oss/kubernetes-csi/csi-provisioner` | -| `image.csiProvisioner.tag` | csi-provisioner docker image tag | `v3.4.1` | +| `image.csiProvisioner.tag` | csi-provisioner docker image tag | `v3.5.0` | | `image.csiProvisioner.pullPolicy` | csi-provisioner image pull policy | `IfNotPresent` | | `image.csiAttacher.repository` | csi-attacher docker image | `/oss/kubernetes-csi/csi-attacher` | -| `image.csiAttacher.tag` | csi-attacher docker image tag | `v4.2.0` | +| `image.csiAttacher.tag` | csi-attacher docker image tag | `v4.3.0` | | `image.csiAttacher.pullPolicy` | csi-attacher image pull policy | `IfNotPresent` | | `image.csiResizer.repository` | csi-resizer docker image | `/oss/kubernetes-csi/csi-resizer` | -| `image.csiResizer.tag` | csi-resizer docker image tag | `v1.7.0` | +| `image.csiResizer.tag` | csi-resizer docker image tag | `v1.8.0` | | `image.csiResizer.pullPolicy` | csi-resizer image pull policy | `IfNotPresent` | | `image.livenessProbe.repository` | liveness-probe docker image | `/oss/kubernetes-csi/livenessprobe` | -| `image.livenessProbe.tag` | liveness-probe docker image tag | `v2.9.0` | +| `image.livenessProbe.tag` | liveness-probe docker image tag | `v2.10.0` | | `image.livenessProbe.pullPolicy` | liveness-probe image pull policy | `IfNotPresent` | | `image.nodeDriverRegistrar.repository` | csi-node-driver-registrar docker image | `/oss/kubernetes-csi/csi-node-driver-registrar` | -| `image.nodeDriverRegistrar.tag` | csi-node-driver-registrar docker image tag | `v2.6.3` | +| `image.nodeDriverRegistrar.tag` | csi-node-driver-registrar docker image tag | `v2.8.0` | | `image.nodeDriverRegistrar.pullPolicy` | csi-node-driver-registrar image pull policy | `IfNotPresent` | | `imagePullSecrets` | Specify docker-registry secret names as an array | [] (does not add image pull secrets to deployed pods) | | `customLabels` | Custom labels to add into metadata | `{}` | diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz index 2833661c7dc72d3cd7e9ab35557297576dfc6373..4e02cb8ad39b6cb1d219deed2aa23cf18314bf25 100644 GIT binary patch delta 11258 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 O!5XrNkq}Lg5dRO}ZEdOm delta 11266 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 UdV@egK|vs>=C96BP0&#P2fJK4(*OVf diff --git a/charts/latest/azurefile-csi-driver/values.yaml b/charts/latest/azurefile-csi-driver/values.yaml index 486cec43d1..757006ab83 100644 --- a/charts/latest/azurefile-csi-driver/values.yaml +++ b/charts/latest/azurefile-csi-driver/values.yaml @@ -6,23 +6,23 @@ image: pullPolicy: IfNotPresent csiProvisioner: repository: /oss/kubernetes-csi/csi-provisioner - tag: v3.4.1 + tag: v3.5.0 pullPolicy: IfNotPresent csiAttacher: repository: /oss/kubernetes-csi/csi-attacher - tag: v4.2.0 + tag: v4.3.0 pullPolicy: IfNotPresent csiResizer: repository: /oss/kubernetes-csi/csi-resizer - tag: v1.7.0 + tag: v1.8.0 pullPolicy: IfNotPresent livenessProbe: repository: /oss/kubernetes-csi/livenessprobe - tag: v2.9.0 + tag: v2.10.0 pullPolicy: IfNotPresent nodeDriverRegistrar: repository: /oss/kubernetes-csi/csi-node-driver-registrar - tag: v2.6.3 + tag: v2.8.0 pullPolicy: IfNotPresent ## Reference to one or more secrets to be used when pulling images diff --git a/deploy/csi-azurefile-controller.yaml b/deploy/csi-azurefile-controller.yaml index 682f934cbd..99603330b9 100644 --- a/deploy/csi-azurefile-controller.yaml +++ b/deploy/csi-azurefile-controller.yaml @@ -31,7 +31,7 @@ spec: effect: "NoSchedule" containers: - name: csi-provisioner - image: mcr.microsoft.com/oss/kubernetes-csi/csi-provisioner:v3.4.1 + image: mcr.microsoft.com/oss/kubernetes-csi/csi-provisioner:v3.5.0 args: - "-v=2" - "--csi-address=$(ADDRESS)" @@ -54,7 +54,7 @@ spec: cpu: 10m memory: 20Mi - name: csi-attacher - image: mcr.microsoft.com/oss/kubernetes-csi/csi-attacher:v4.2.0 + image: mcr.microsoft.com/oss/kubernetes-csi/csi-attacher:v4.3.0 args: - "-v=2" - "-csi-address=$(ADDRESS)" @@ -95,7 +95,7 @@ spec: cpu: 10m memory: 20Mi - name: csi-resizer - image: mcr.microsoft.com/oss/kubernetes-csi/csi-resizer:v1.7.0 + image: mcr.microsoft.com/oss/kubernetes-csi/csi-resizer:v1.8.0 args: - "-csi-address=$(ADDRESS)" - "-v=2" @@ -117,7 +117,7 @@ spec: cpu: 10m memory: 20Mi - name: liveness-probe - image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.9.0 + image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.10.0 args: - --csi-address=/csi/csi.sock - --probe-timeout=3s diff --git a/deploy/csi-azurefile-node-windows.yaml b/deploy/csi-azurefile-node-windows.yaml index 4319db7002..f0563deefb 100644 --- a/deploy/csi-azurefile-node-windows.yaml +++ b/deploy/csi-azurefile-node-windows.yaml @@ -42,7 +42,7 @@ spec: volumeMounts: - mountPath: C:\csi name: plugin-dir - image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.9.0 + image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.10.0 args: - --csi-address=$(CSI_ENDPOINT) - --probe-timeout=3s @@ -58,7 +58,7 @@ spec: cpu: 10m memory: 40Mi - name: node-driver-registrar - image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.6.3 + image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.8.0 args: - --v=2 - --csi-address=$(CSI_ENDPOINT) diff --git a/deploy/csi-azurefile-node.yaml b/deploy/csi-azurefile-node.yaml index 881a516b6c..db4f616235 100644 --- a/deploy/csi-azurefile-node.yaml +++ b/deploy/csi-azurefile-node.yaml @@ -42,7 +42,7 @@ spec: volumeMounts: - mountPath: /csi name: socket-dir - image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.9.0 + image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.10.0 args: - --csi-address=/csi/csi.sock - --probe-timeout=3s @@ -55,7 +55,7 @@ spec: cpu: 10m memory: 20Mi - name: node-driver-registrar - image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.6.3 + image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.8.0 args: - --csi-address=$(ADDRESS) - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) From 03f8449e2f0bf6f99a384e81d2a364acc17c80c8 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Thu, 4 May 2023 07:53:16 +0000 Subject: [PATCH 072/109] feat: add enableVolumeMountGroup feature flag fix chart --- Makefile | 3 +++ charts/README.md | 1 + charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 11661 -> 11690 bytes .../templates/csi-azurefile-node.yaml | 1 + .../latest/azurefile-csi-driver/values.yaml | 1 + pkg/azurefile/azurefile.go | 8 ++++++-- pkg/azurefileplugin/main.go | 2 ++ 7 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f48c3c0bce..149e3b9490 100755 --- a/Makefile +++ b/Makefile @@ -33,6 +33,9 @@ E2E_HELM_OPTIONS += ${EXTRA_HELM_OPTIONS} ifdef KUBERNETES_VERSION # disable kubelet-registration-probe on capz cluster testing E2E_HELM_OPTIONS += --set linux.enableRegistrationProbe=false --set windows.enableRegistrationProbe=false endif +ifdef EXTERNAL_E2E_TEST_NFS +E2E_HELM_OPTIONS += --set feature.enableVolumeMountGroup=false +endif GINKGO_FLAGS = -ginkgo.v GO111MODULE = on GOPATH ?= $(shell go env GOPATH) diff --git a/charts/README.md b/charts/README.md index fcaa9fa46a..af3e0c9edf 100644 --- a/charts/README.md +++ b/charts/README.md @@ -52,6 +52,7 @@ The following table lists the configurable parameters of the latest Azure File C | `driver.userAgentSuffix` | userAgent suffix | `OSS-helm` | | `driver.azureGoSDKLogLevel` | [Azure go sdk log level](https://github.com/Azure/azure-sdk-for-go/blob/main/documentation/previous-versions-quickstart.md#built-in-basic-requestresponse-logging) | ``(no logs), `DEBUG`, `INFO`, `WARNING`, `ERROR`, [etc](https://github.com/Azure/go-autorest/blob/50e09bb39af124f28f29ba60efde3fa74a4fe93f/logger/logger.go#L65-L73). | | `feature.enableGetVolumeStats` | allow GET_VOLUME_STATS on agent node | `true` | +| `feature.enableVolumeMountGroup` | indicates whether enabling VOLUME_MOUNT_GROUP | `true` | | `image.baseRepo` | base repository of driver images | `mcr.microsoft.com` | | `image.azurefile.repository` | azurefile-csi-driver docker image | `/oss/kubernetes-csi/azurefile-csi` | | `image.azurefile.tag` | azurefile-csi-driver docker image tag | `` | diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz index 4e02cb8ad39b6cb1d219deed2aa23cf18314bf25..5b8bab217a3e742f286170ff93c2687941e896c5 100644 GIT binary patch delta 10502 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 Date: Thu, 4 May 2023 09:04:25 +0000 Subject: [PATCH 073/109] feat: add fsGroupPolicy chart config chore: update chart file fix --- Makefile | 2 +- charts/README.md | 1 + charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 11690 -> 11697 bytes .../templates/csi-azurefile-driver.yaml | 2 +- .../latest/azurefile-csi-driver/values.yaml | 1 + 5 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 149e3b9490..797690a497 100755 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ ifdef KUBERNETES_VERSION # disable kubelet-registration-probe on capz cluster te E2E_HELM_OPTIONS += --set linux.enableRegistrationProbe=false --set windows.enableRegistrationProbe=false endif ifdef EXTERNAL_E2E_TEST_NFS -E2E_HELM_OPTIONS += --set feature.enableVolumeMountGroup=false +E2E_HELM_OPTIONS += --set feature.enableVolumeMountGroup=false --set feature.fsGroupPolicy=File endif GINKGO_FLAGS = -ginkgo.v GO111MODULE = on diff --git a/charts/README.md b/charts/README.md index af3e0c9edf..090d4f4d74 100644 --- a/charts/README.md +++ b/charts/README.md @@ -53,6 +53,7 @@ The following table lists the configurable parameters of the latest Azure File C | `driver.azureGoSDKLogLevel` | [Azure go sdk log level](https://github.com/Azure/azure-sdk-for-go/blob/main/documentation/previous-versions-quickstart.md#built-in-basic-requestresponse-logging) | ``(no logs), `DEBUG`, `INFO`, `WARNING`, `ERROR`, [etc](https://github.com/Azure/go-autorest/blob/50e09bb39af124f28f29ba60efde3fa74a4fe93f/logger/logger.go#L65-L73). | | `feature.enableGetVolumeStats` | allow GET_VOLUME_STATS on agent node | `true` | | `feature.enableVolumeMountGroup` | indicates whether enabling VOLUME_MOUNT_GROUP | `true` | +| `feature.fsGroupPolicy` | CSIDriver FSGroupPolicy value | `ReadWriteOnceWithFSType`(available values: `ReadWriteOnceWithFSType`, `File`, `None`) | | `image.baseRepo` | base repository of driver images | `mcr.microsoft.com` | | `image.azurefile.repository` | azurefile-csi-driver docker image | `/oss/kubernetes-csi/azurefile-csi` | | `image.azurefile.tag` | azurefile-csi-driver docker image tag | `` | diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz index 5b8bab217a3e742f286170ff93c2687941e896c5..99f20d98a2d4e9af5be54d4c65113eee9767f08b 100644 GIT binary patch delta 11583 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 delta 11577 zcmZ9SV{qOL(C&jqjomah8r!yw#z|w_`G<{dtI-`bjcwbuZR0-AJ9FMSGv~|B?6te! zclUSI>VkCR1p$1nMu*SCQsEgkv$xpHLYy@=--FiT1gtm%TN%ocku2P!7txI{3ds#& zIAJvt0^mtY+uLwiub%s)Q;wc96?)s2`+0}`lVO*cN|3vnBz9;7>G^R7%Y`R>uN!QS zIpxSr(7Cy_1SUiY8vvttco+grbzNO;;Ma$W4XwT_qThTq?oW?hVtq09o!b#1{qJo% ztA5yUPci)56hcr5Yxs~)2~Qlrkr&+o@cRS4e-KN!?)~cg3i&DWwhL@tlLQX)ln$U~ zJ|%UHfzcBlmZWifAt7P32#PuAHWNWDR;`F6>nHscBt3XUUhjA3QG4b9Q!7Xz#YAZDJAA(MWj=OyWWR7Wh!&DvqSJx%W5gERLZDy8~MT zD8!blP*g~QAG zHh$4R0R$vPK#`$%)yPFpr_~6A!r=q9>(Xx}i#Lw_nE3zl@o7_-E7Sa>2 zCZ?`dCx6A)Bw`|r^lEAjhE1|EXEd!9lnEkflfq!U_qLWOnucm>b+ZAE@b<3xGqb}V zUVuKA1BfS2Vza<}DY?`(IM&~)zEsQbXUK9Wx@zxscuRb~UEo#S+8#;rU0=PTC`Z^d zH6spr{hFBNXb3-y*VwZ{ua>jy7YveO452iM&QkLMawx;MZQ2r5#%I8tR) zmPkRp-2Me0=@AI(YHka?*y&3lgR66`3ZR?T$WU?4B$AhChV2y+v0PKV&i1`X|I~$8 zP1+Fe0D$b03<*yAysR7XNe>hft(iB}Vd+n1jYzp80AsK+QJ0b4p~!}E!{a#NhLCoS z@`6-g#Ur1YLe`nT7v$_uK|ob`86t-fhkvB>)u4wv7aJ>s8u6FtRz||kc`Vq8fq#2) zKh~X3COsC<+k?D_E3bm`mRh$q8eTPC2O6yZY-y>o5n;;iugeCjZlrAo|G;Y!k~xHK zA}h*rn?@d&Dyv!Gw-7|SrQ)A9*=(ZttGu9D^$>Rz9#7^ExyRD%9P(OvKARJS`!emY z(7B*fF#GLkGpbIKOTdnRctY^F380>*#`6E=kJXLJEaa$9(jw?7*6{YcF zAOiDb(pMP?y{1TyvV{+V&#h=hTytTH)kPYteuX_UVfqlY{WUT_m3qB7JSR18fUix9J1mOKR;ZSAFp`JCn z;W{?4#V)bdfvikP(L)3ZiqwQ<(E?O$h+TBT2NN+SzkP0Y6w3CGTNq?U;WT^-NZ9*_ z3bFzAL+)Pd?Iu5a*;MO-8pF3?C;Jr1%XzWAI^jQSbd0wLC>0U_2 zNR+(n>Q4;h!+jS=V27ArfH^!X1)VoTvosI&>+_R$ZlWD0YOn$HL#y7Z=`ccy={&f? z@ssWqcu`3QbRn=`^}|MzKTp9`aj$uA717}^kZPYvDqe*Nv(3pXm+4ea-*5=*Ff(6o zVFpwU3_y^eN}00w^wtu0m7PUQhewN;itI@H#CDRas(8ATTfvD%=awoD)j@8dz=1W_K98o7YaS7uqLfl zFLmw&sXlNznU#OdM4%5j63@4|ukmFmI*v5g%EFj$Kfc(rm=jQL!v}s}6qGkc$Ags~ zp*NvczoO(1t?p;Z5jGV_7G|6mUqUKpZXH^jetM(-3ub)EJ{RehP4AX`>#BP?d^m#w zJ{>$Pt|sg)z{I<>@VfsdIVVdgyPdKPaHyljpgb_jP+XAgKke0*6|a6PJN(*_#pTR* z|H6AN`t4%CvRH*w-eR&(6@KDNnP%J)`i;Og&j&X?$|C~-QdobF@$d>#dpj>-fj`n- zCK^vnH5?;iq=lvRmuwRupX5>zy|p(!0DL@TNzi+YjUX&d5JE0azNLiXVg8CnQ=OB+ zYiu;-ZsJY$CFU|CJ*lwOq(p}g-<;|KGP%kKI!W|X`Q}z2f;82?zt*r&u?tgeaH7_Z zASP=CH$;()_|Bw(NVM0CG+Ox|?wvP{dztGGl-^t^dFd0q7Rhc@4ScJ9rZ8e5pn%9J z#au4`Otr(U@PR%d1;vsNQ)w6`>Vmw)#{sndAv0#T^2AhEQy{gK@XXMxUvn| zAyMh#Y=Z&H7~+r^`&-`m(6-*-z66Oq_Kxg=FMXxHB zX7`Y2f8d+zSrU^v*IAvj+QGU4Q7RQ5HBR9ps&Vm@ zG5S(%IzNd)nS8HGIl9Ka>gc~$Q+qJjRLR8#`fNN5?&Xh(3-_|W10utN%foo`Lu1ckx%e!#OQ;8i>yQGm?fQ1fd&|JP0bBr3Xl_CvPo1lg&Esz#TlT!gsE zCz9atw zIEzcl>#AHW^5sYBce)z&q2H92byzh*g4HUt(7*B^2FfK0sg81cv;>!|hv!y^tPz&4 z4B$~(bwFO9^HWx49lwcRGsnE>h!rgiD$8>~EStH)>aD=1DbTzySSds`o(}4f&p_3z zbGk4$7KgHS%Z4-ng5j1WFg`H|e#$6c3QSXb->Ah0V=KmjND9R#k(*=nq!OKKFM5#P z?L??h4lk3X9nJcUb-i*jwLv*cBHIFTld*Y6R5cXZhcngsee^%BCjUm2TT7~N=Hd>e zX^qsnX=?qEkl>xLj)W(K=Ax{sf@&C9K(dIt2sdFs*M}1asC?<_RR!jW+8)P6mH23n zLkh(R0)TLs^*4%&6|C6IcK0~~pAEOU%FUzYW#|ICR=xp(HjL&(Qmt=2a{bH}vN7UX zC>^`6;bUcp1z2mExc2zyijTy*Iz1LrEYrU6#7+%JXCgM{G{iVZzwLP>6$1Y8i=Mb$ z7?no0d$t4vbw&Zz?0aa}96pI8;eTKicWUL?zZC^1pJL!Wgq$_G+1qLC^rl;%ng7;t z{W(=}I{ykDJa%|NJ=rO#pI(;a=&Dx??3`sQ)--FfJ6q({rw+2G`0|4{HkE`a`` zF!2ndcCY&0bl|brooB3Kk>uBn+F5#&cI#>@hnyBO;B?_ZkY0k1(v}(FXDih65|fZ? zAoTL7Db`MzGOzJUY2g?SM$7V zI-iCI7TM8t2XXquV@@ItoS+u*tY8AkZp-xZcJ(Uhl12%zQHC8gRqy!5$gvf2Uj z?5V^eRGFWpZ7J_u?&DV%h2xek*nFC9y%@|WAbppiu0`5HRgG=1f9XO#AZT;@2TY+} zBIIluz6p4|u;9J})(2CS%EW+qBgP~rTpNDF2dT;M?Nq*%<{c6+@+W! z1+g!9UU%wvNK7&XSuOV$#d)lE?m2(8$R?=VuEUr!8Ii+-Y&K13Fd@!BZz`opj^B0y zU`&;>?~h^1T669aUt-p*L_?Ufv{JLn^*;LJ71be~#<65yFl%i}CQgrz#e-+z3JvLi zh@L^im0;a;ic`AG+=7$uI`H0-K~VQ#`^N{xIY4o$I#%j9l9b=HUyKwphz3_R0N*K? z9t%C3p@HyyuXYUsL;}424H)<*Vd|d zfC~6K;xyM(!>`36Bl!#Gv()B896U%c%Na7g=sqdk96_ zX&k8>dyScin!wa(HL7Q5hX;fxMH3l5?netlCZdWL3Cm5ADIuti5W;X6J`xp!G<-sA zUF1BvZbV!re72Wj#afMTBwd*z;49e((mxdW&_@04+gG>ZMh1l-+r@fwV7f{BS81Vl zT$8pmuIk2LO!+u*+;Hcg%zK!X-lA{J?xIPzI{&5;Jn7kL(?d8a`%`bI?PVrh5t1y6 zfdTU4r3|d@$9l~KS(=Xj^RGo?heMH|hcD427dTt+%S03Yb5ax2& zj)cVC(OJuv8|m!k@PLMP06Pb6xH6fi5R`Mtz^3Isz-p}Kx9a6xqQox|@Nj=p)v_~@ zj4-TyB`2PmfXOqQ%z2h(JHK}2!0x1=M{GhHIEVfUFbRHKcpM!7U7k00(=S6zfX|Ip zKKRCv3H)|&bwdpJyxa~%0SQ74I4lJp8c1Q_FpFxrRrri zlDQ1eRWzR@D6uULaa@?^&-O9x>B1r_ie8Cd8^Z7>hJM=R@!D{3i~W*u5U;#)7{V#D z2q9Hj-|(>*UTIPS)& zeD>kNh}LOQGXTS(IidI&A;OOr}Be>rQEK|Qvc2O6!Chh!^NF$tGu3UC&^>s1OMqm!BPWxX*%I?vPEdi zZluZEIXIX?4-;1A*<&)`6IN?xjl;db5{qm9Xcv}p;x>7G23EHgsvys+msZthIsI8i zeG`#GM!72E%E)(p`&qeLTz2Y*NSozxgD{!u$AejKvjA+)k&+!(wgah^Je(exSYasC z`xk?D%5p>?t=|WQ=YT#_y&xd+#vIi*{zghD0*jME4Mt!Z=7%HAE3)yt?*Nt1BuEQ; z&#$%I>fD!-nw#{HTN%-$3aT2_i-uS$Jz}DpOqQAx&gsnFY>7f)%tq{v*Oops;uZa8 z?7>i&9ri@vwDONp%S?^+Ghu8cSoMUo;@>ZmxavN@G4&tv>EauRB%MY1r7mTBztyFR z*(H$3g+OB7-iM?aJx|G|?LN%cQWp`ubBh3pdJ!xQFc;dW$m~srN1D7OM=XRT7S@zC zl2s`2#C^RA>-^Cl7DR6 zB0(58Ovn|N78?Hgs72O$v-FuMy2Bt|kvs1meS+3h^j%6pA8QR&=t<>c>b%?i|AKC= zqU#a5(l&qZ@iiQG{4lV7Qz?+hY=%Q9tDShJL^%sEa7Rm9{=DPf%^IUoZq~f~N20FD z;lZDssE{DoX-{I)GPY;^m0B}}e$zrLW05mgirmP#uFb)Z&ktJndR6x%ERDK0C%k14 zik{uu^<-x$)_8(hrcc59g6Rl-7NKQnn~fL!Z2hf^ZGo+vG;8VrcI+c@{Zml!L6g!|)l)vcgUY#zB;rqS9o}36#o;@cdKsP`-Ljgp}R9 zbfw51p(oyR1UWDQMQ>M3mke^=VfEpp2!~^wB-6MvFxldC=A0q==Ew?9 z`YuXopkaF=|D{)0aId0lrC@*e8q_99TyTN`@VJJZ_Ii{thAia^D=W~{(8o9Iw8y;7 zANJEs7A5O#4rNp)K^GyZwL^PdN@0qoINa|R2fkeh<3gwZ;ECR(#WnlTpgCmwPc~?Le!v;7}gqVJ8Ozund4|l_!NUy1F z5IMc0&!mzLMt)45ttlP)?p5sN)w@BRAo`r!hITV7Gb^?>BYU|6#P^Pt4G$Kf!Qxe) zB|{yqb>eUOHWoC2QtFyM_NXI!KB-IngZb ztr!R3#pxvWJDCiHFo8FY}62TlSb7~!0AoEox`}R>2 zvjQpbU&XThh@Uew`TSBXsQ!#861wYg1~F*@RP%YBg_5K#sp(WgnAHJCofOf@U(s}A zjrgug%g!p9Z1zD4!tr(5k|YYX1@1)ju!YOV)IP=q+v+|hi5>6yZOO5o8F#$uTnp%#m|&aH@4%3G zx5XFxCI`GOQrBIYL1){<7`rNGN97SHE#PTCM$UixV_yV7!(a!5y3_2pr2WTx-0v$$sB z=ufyV#u+tadMFJMa%FvMn$mM_MgZ1o-So696@6OBu`_ExrA5eYGK*i6FYk=XMMjre ziv=k)n}Ko?N|KniMGQ-gs@shBCIy5#ZpW|pA97EFc2Ri%tH*`Ge$Ue z0I&gp4`RN3eh++a%W71S&uo=+nkc@swVs8xcFTJ; z-Tciy2`^^ak#?@@_`d99Kb)NikHKko**x;}zzl?x^zttx(+M-H$%b-)7Y(!?iU3EN z3Sa6$41Jd0ri68-8f z+nVa??g+ozyZ+%&qM$h3LSDM8;BI!lTuHIu z_xvq%%6T>220sm{lqJpTLVdN7nQ8J%SDq>RJ_+! zovk^KQT%Q9R+`bjcrQ2!!MPAzPdg{3vH+EAfR$891XQ~;;aDQQTF08z9}2DIz^xQD zN($zk`?(5bMx=Mht(`Td_a`+1{T3nS^1B7~n(Em}^-fylUy1u@|87yJsbsAjp6r)+ za8SQ{J|b1BU?1HDA0IoA_m(ai#kd#XQ#Q)=NZ{Pdop6UWZ|ui6#IdFCsHez2SmRU( zP~HXNdNJRb$`RSBmzsV&#CiQ5x?qxH_OvRL37~c)dikVmCiwOHbvH|o$*tioC+$Ay zg;XG9g12Zen(m2CBK0Ph(j#)9MK!{stZQS+L&y<^N6CgpuKPKur z>ymaiObC+S$4~F2`A16?s|f1jv!zZQ0NPMk&YN?|!XOvD*Ox5vh|bUA(Y?v=RfVr> z`EGu3@50c4fPhe+z|f$xlI9rtF@W#q7@8z*nzWG7Q{yBi$WlBJLYrdi5;?4Jmt$Qf zmN3}b*~IjX(;+{xS5}9cn_{x2!1K*|S$&sxSG02j@9-;R4tD9xCIRc5`WLQp;Nd%I zgPZby8{K#ZEo%@4Srn&K)FQY1=waH@7g#}>Hr1bp!XMVvBDCMXVtqfw)+Zs1`_;6% zqD1cJ6#13pC~zeR#+fa5Y|=h;yK>l+wwBM1;R>$tc`&r2bw{>bF0z{O(B`S}cR*9h zmG-5(d&T}`Uc$PNz7mU)qIxEU3C_3L$$Cj6dsl(yYJR!cqQ2>AFThZNvO~(mW3n=CX%0Qy&S%~p zMUU|plr*fYZ500^-Fj5R4Fd=o5GlzbbeqtBvk!Nuh?H41jwf36V8a+~#?r*Za-%@yk^ z3IwE1aGg6UIDezY=qBWcr28>wKkEA*oK%lE{XL6Afc_r>tS&5|vENlqE3=1x6Kr!M zfj{8qg64o;9Ej66>2o~}P38D39^RE<*RECHkdf1kA#jLSh}imiB|1srk|89j6?Rk+ zpJ4GhnroMkDsVKIk_TkeI&D^$5cDU%Y{GYpcI3(8bwcZW=?sy)TaphT(p}*DFm^g8 z4vafWgB{=#_3;vqZ73f(%XvRT<2E*MJMfOX1N*mgfBJel`MUagyE$Kf-aS!Y#Z|md zUGY>%Ga6~%LZbiyUI$ew$s7u?V?8eQfplqYfiKci1_OLJnZQ{(9<#g?i4KGAg^*P8 zdQ4-}SqH8SJ1y3MhT$Uj(Ybx>>&HJ#6Zq$)g@u=cqr0d&@ZHtv=a@IioPEKJEObLa zFXtCVr7hO|gN)OSm81Wts9=|n&(q7tP2AAc+9OEkfUu4Kb;r-zB<=P_H5i;<@M>Zf zZ-3}Nfu)k+U%M){=@{>_mlnMQZEA`suMW2xk$_wS-fi)P$sK`X<$H_7w zhj?~UU+Q++Nx9nK>)*C*%L)7#&boOhE&rH@2RG?-Y++D&cS65kt@wX*`C|NR>0c!v zMz>dsIJ8l(K1fE;>Fg(9JVXnI$b$L&5b_rg-N^9*8%2eLGnjTrlrPmzSINVPN0zA*XDD{kmkwe->zk|6M$s zX?En_*t;AUg!$73>~S3JKnPlBVv;W5WU>7DNY4HlE|tyx(eZ3>kGLaCqBfkNEvn{U zNbeMnf%F`eiw}y_rRAQdUr3kh4?ECzBqL#d)r+Fi`Lmyn1d5~(u_<_XQ6AY6#^=%c z5Rd-5;=OooJO8orEklC|G0U2Xv_t?|xQ%k&w8;d4;V%TZqmGY$r|apF?*)i2g->dT zLd5#dmEiYbJphIm>prHe3_y*`y6-=M-PzFqs_Y>MiMZMX+4=3Qikcmh-tJYM>5Wa; z+~^L(j`xfFvH5}^JKv;lkT4CaOzjVo(NJ%%_DJWA?O|@rJbe)QrR6V2#ok38ZDC7TD|R;!+HzZ! zTb477SGc*pJKoDUWq$%=&?z4Wg)5`_{R^Bw zXb|~m*c>!cutN_8y}NKBRjC%?GU#(9eM7Ysw>}RBW(G#$hH&$kVz>PMyD#2%?p}Hp zx<o3&SJf6-(_eTotc$}czIeEmsf~-pXqWmQP~b|` z?YGW1YVExAFSxX~mnGQlaM%LM1JUk|l~Q4*cyU&0!t@K@Z#F*J_V z%a8wl86&)Qs)2(i5TFR588-zfq3(BKt@nswt86DD0oUci4cUVdHy%JwJ8aV1`?&JC zzPNClO6BJSqfyxWDw^tC~f!h`2Vl$Cu=jA*y`4y>^P^EaP@#dwpJuO|zEma!C`MpA|P8~Q(fi=I#u!OJSP|<>F zXZ&lb;F=o!(~0VmArGD(+w(b-<7JRcxBueAW;CpxUi%v@lL6Ex>lVM|389#8yDL>6I5MR%a0 zQoGkAht(za;}F1#ak4JC%v=#iR(J{~t;^i$MEga1qJ%D_$%ci5!7GKQM_)EM=Ec$~5&D3qgL2h8NPiA0z_3w@+6iIDluM#XtQzE<9d|Sc|5m{_<``ogVK2@$_Pb@cbmA0DQ%Gm!wAtC9kbk*u|^+Uw!PW z)^S}1n)7SDEtFgvC;Pvv5ag`2qj)#QiEqqBl&_G^ksNkJ! zkkN|>`Yxj5Q;0D?ZT)NE@;nPc_Xnzea5K|!1I?S;^&i-r>oBFDrz2>phHh|w`9IB% z_p8EphqoF7+#8`bhs|@3=e#h_uRG5a44I)2Rx*G#7{5oR?nVgZj@W(!jk!#N3%~m- z$3vZ9P+9rI8+g=F?Mlwy-E-i;i+@_#28t`52UK2zEbNEF4yIt0Pm$5Z9x_$%e{x%+ zhVj%<{HOWeYhWO-aTWG>`fB}D+$Mj4?C*Z%Z)xqIo@( zAWFZIwa^2LnF=zcqw;JSrVS=!vnu+}4YDM0wK|FA+pOj%LwjIw5BNW-9l!ED*&N0l zCOGU`qx6!_9Hp6r_+LH&C)n)6QybhVA+&COC2SR>5;-%NNC^OS-XgSDcsEk&9Z)t9Sd6jsAeHGEAD&w_DhpMf+28!t z6G@(Ho`I}dFtQHDnYH(t)U-TzN+P7y=(HT5dv(FvBP!4dtT~liyJ~I3WDG9_W@MFO z@l{bGUV8sCUg*$%Bq_&DkN6!^`805-$SpNiJg_H){}1o4A03H4Vr}A?ok-m{euo`p zu*+WUS57u>2#Yg&=!~t7&G=({>%;NGv&NkAbN!RcRPD6kZ7?Mn7QTL=DkOI0^z?7B zGiwDly{QbRiI8lE17d_(y$l)fX&cFg-mYk~SXNjHVwHGhNe)}gTu|Ki-ZU-7x9!!_ zFlkgFwh`d++3VEjb%?^&0sTCEIBmUOuv}5hO0Bojq~Z(xSyT4&Y(7k*eBIX)tm`70 zrcq(j&#`!F>?UxlEP0&pupm}ZfqeT$EUbiWzUSnc{4;fxQjUtc)8G#1js*1(%Xz(~ zW$LUzFfnoQ065U?7-RK2mrRDOOjCk^7B6>Q2T1`8-QbJ!i!0n4pvIuty0hjc*Nz z^=*{_OZgkbOaz(|$&ggk&HFy}!g1d){2f!7#;vI#6~-Tp@Uvk)yK<;)53M99o(rF+ zt`%-RkIr&77{PDB`~z=!q211>=eW0t>XAS12&WIzA8wn30Iin67WuDN?k8<7X@{Ah zj6=fR1EKvH@d2_(O6B$6CTjM^ODl(Ti~~X^KJ*)Pt97xT4n7!vmBC$%gWxB_u9b`X z|4deKCEz(`=h7Fxi7kP+d-@u1nh=6^J~-^nN8$tQ&3%3e2oBfDzk_$8#WwukjpZdu dk6KH8T92mCuHV5B5D;Ln*s5|2L_H+L{{cV?5t;x1 diff --git a/charts/latest/azurefile-csi-driver/templates/csi-azurefile-driver.yaml b/charts/latest/azurefile-csi-driver/templates/csi-azurefile-driver.yaml index e1facb056a..8b715aee64 100644 --- a/charts/latest/azurefile-csi-driver/templates/csi-azurefile-driver.yaml +++ b/charts/latest/azurefile-csi-driver/templates/csi-azurefile-driver.yaml @@ -14,4 +14,4 @@ spec: volumeLifecycleModes: - Persistent - Ephemeral - fsGroupPolicy: ReadWriteOnceWithFSType + fsGroupPolicy: {{ .Values.feature.fsGroupPolicy }} diff --git a/charts/latest/azurefile-csi-driver/values.yaml b/charts/latest/azurefile-csi-driver/values.yaml index 2c98635344..dd10442b12 100644 --- a/charts/latest/azurefile-csi-driver/values.yaml +++ b/charts/latest/azurefile-csi-driver/values.yaml @@ -157,6 +157,7 @@ snapshot: feature: enableGetVolumeStats: true enableVolumeMountGroup: true + fsGroupPolicy: ReadWriteOnceWithFSType driver: name: file.csi.azure.com From 069d427047163d5305b0b07f892e2334cd7d97ac Mon Sep 17 00:00:00 2001 From: Ji An Liu Date: Fri, 10 Feb 2023 02:47:24 +0000 Subject: [PATCH 074/109] support host-process containers in helm charts Signed-off-by: Ji An Liu --- Makefile | 23 ++- charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 11697 -> 12111 bytes ...si-azurefile-node-windows-hostprocess.yaml | 180 ++++++++++++++++++ .../templates/csi-azurefile-node-windows.yaml | 2 +- .../latest/azurefile-csi-driver/values.yaml | 1 + ...si-azurefile-node-windows-hostprocess.yaml | 125 ++++++++++++ deploy/install-driver.sh | 17 +- deploy/uninstall-driver.sh | 1 + 8 files changed, 345 insertions(+), 4 deletions(-) create mode 100644 charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml create mode 100644 deploy/csi-azurefile-node-windows-hostprocess.yaml diff --git a/Makefile b/Makefile index 797690a497..6534021b39 100755 --- a/Makefile +++ b/Makefile @@ -95,22 +95,41 @@ e2e-test: go test -v -timeout=0 ./test/e2e ${GINKGO_FLAGS};\ fi +# In the scenario "host-process" and "csi-proxy", use the same daemonset name. +# The command "helm install" would validate if the name is duplicated and return error or not. +# So here we have to use flag "--disable-openapi-validation" to skip the validation. .PHONY: e2e-bootstrap e2e-bootstrap: install-helm docker pull $(CSI_IMAGE_TAG) || make container-all push-manifest ifdef TEST_WINDOWS +ifdef WINDOWS_USE_HOST_PROCESS_CONTAINERS helm install azurefile-csi-driver charts/latest/azurefile-csi-driver --namespace kube-system --wait --timeout=15m -v=5 --debug \ ${E2E_HELM_OPTIONS} \ --set windows.enabled=true \ + --set windows.hostprocess=true \ --set linux.enabled=false \ --set driver.azureGoSDKLogLevel=INFO \ --set controller.replicas=1 \ --set controller.logLevel=6 \ - --set node.logLevel=6 + --set node.logLevel=6 \ + --disable-openapi-validation else helm install azurefile-csi-driver charts/latest/azurefile-csi-driver --namespace kube-system --wait --timeout=15m -v=5 --debug \ ${E2E_HELM_OPTIONS} \ - --set snapshot.enabled=true + --set windows.enabled=true \ + --set windows.hostprocess=false \ + --set linux.enabled=false \ + --set driver.azureGoSDKLogLevel=INFO \ + --set controller.replicas=1 \ + --set controller.logLevel=6 \ + --set node.logLevel=6 \ + --disable-openapi-validation +endif +else + helm install azurefile-csi-driver charts/latest/azurefile-csi-driver --namespace kube-system --wait --timeout=15m -v=5 --debug \ + ${E2E_HELM_OPTIONS} \ + --set snapshot.enabled=true \ + --disable-openapi-validation endif .PHONY: install-helm diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz index 99f20d98a2d4e9af5be54d4c65113eee9767f08b..8a8beae63121163247daa7ac13ee6678716f71ba 100644 GIT binary patch literal 12111 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 diff --git a/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml b/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml new file mode 100644 index 0000000000..866915e8ea --- /dev/null +++ b/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml @@ -0,0 +1,180 @@ +{{- if and .Values.windows.enabled .Values.windows.hostprocess }} +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: {{ .Values.windows.dsName }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Values.windows.dsName }} + {{- include "azurefile.labels" . | nindent 4 }} +{{- with .Values.windows.labels }} +{{ . | toYaml | indent 4 }} +{{- end }} +{{- with .Values.windows.annotations }} + annotations: +{{ . | toYaml | indent 4 }} +{{- end }} +spec: + updateStrategy: + rollingUpdate: + maxUnavailable: {{ .Values.node.maxUnavailable }} + type: RollingUpdate + selector: + matchLabels: + app: {{ .Values.windows.dsName }} + {{- include "azurefile.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + app: {{ .Values.windows.dsName }} + {{- include "azurefile.labels" . | nindent 8 }} +{{- with .Values.windows.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.windows.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + spec: + serviceAccountName: {{ .Values.serviceAccount.node }} +{{- with .Values.windows.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} +{{- end }} + nodeSelector: + kubernetes.io/os: windows +{{- with .Values.windows.nodeSelector }} +{{ toYaml . | indent 8 }} +{{- end }} + affinity: +{{- with .Values.windows.affinity }} +{{ toYaml . | indent 8 }} +{{- end }} + nodeAffinity: +{{ toYaml .Values.windows.nodeAffinity | indent 10 }} + priorityClassName: system-node-critical + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + securityContext: + windowsOptions: + hostProcess: true + runAsUserName: "NT AUTHORITY\\SYSTEM" + hostNetwork: true + containers: + - name: liveness-probe +{{- if hasPrefix "/" .Values.image.livenessProbe.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- else }} + image: "{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- end }} + command: + - "livenessprobe.exe" + args: + - "--csi-address=$(CSI_ENDPOINT)" + - "--probe-timeout=3s" + - "--health-port={{ .Values.node.livenessProbe.healthPort }}" + - "--v=2" + env: + - name: CSI_ENDPOINT + value: unix://{{ .Values.windows.kubelet }}\plugins\{{ .Values.driver.name }}\csi.sock + imagePullPolicy: {{ .Values.image.livenessProbe.pullPolicy }} + resources: {{- toYaml .Values.windows.resources.livenessProbe | nindent 12 }} + - name: node-driver-registrar +{{- if hasPrefix "/" .Values.image.nodeDriverRegistrar.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.nodeDriverRegistrar.repository }}:{{ .Values.image.nodeDriverRegistrar.tag }}" +{{- else }} + image: "{{ .Values.image.nodeDriverRegistrar.repository }}:{{ .Values.image.nodeDriverRegistrar.tag }}" +{{- end }} + command: + - "csi-node-driver-registrar.exe" + args: + - "--csi-address=$(CSI_ENDPOINT)" + - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" + - "--plugin-registration-path=$(PLUGIN_REG_DIR)" + - "--v=2" + livenessProbe: + exec: + command: + - csi-node-driver-registrar.exe + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --mode=kubelet-registration-probe + initialDelaySeconds: 60 + timeoutSeconds: 30 + env: + - name: CSI_ENDPOINT + value: unix://{{ .Values.windows.kubelet }}\plugins\{{ .Values.driver.name }}\csi.sock + - name: DRIVER_REG_SOCK_PATH + value: C:\\var\\lib\\kubelet\\plugins\\{{ .Values.driver.name }}\\csi.sock + - name: PLUGIN_REG_DIR + value: C:\\var\\lib\\kubelet\\plugins_registry\\ + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + imagePullPolicy: {{ .Values.image.nodeDriverRegistrar.pullPolicy }} + resources: {{- toYaml .Values.windows.resources.nodeDriverRegistrar | nindent 12 }} + - name: azurefile +{{- if hasPrefix "/" .Values.image.azurefile.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}-windows-hp" +{{- else }} + image: "{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}-windows-hp" +{{- end }} + command: + - "azurefileplugin.exe" + args: + - "--v={{ .Values.node.logLevel }}" + - "--endpoint=$(CSI_ENDPOINT)" + - "--nodeid=$(KUBE_NODE_NAME)" + - "--metrics-address=0.0.0.0:{{ .Values.node.metricsPort }}" + - "--kubeconfig={{ .Values.windows.kubeconfig }}" + - "--drivername={{ .Values.driver.name }}" + - "--cloud-config-secret-name={{ .Values.node.cloudConfigSecretName }}" + - "--cloud-config-secret-namespace={{ .Values.node.cloudConfigSecretNamespace }}" + - "--custom-user-agent={{ .Values.driver.customUserAgent }}" + - "--user-agent-suffix={{ .Values.driver.userAgentSuffix }}" + - "--allow-empty-cloud-config={{ .Values.node.allowEmptyCloudConfig }}" + - "--enable-get-volume-stats={{ .Values.feature.enableGetVolumeStats }}" + - "--enable-windows-host-process=true" + ports: + - containerPort: {{ .Values.node.livenessProbe.healthPort }} + name: healthz + protocol: TCP + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + timeoutSeconds: 10 + periodSeconds: 30 + env: + - name: AZURE_CREDENTIAL_FILE + valueFrom: + configMapKeyRef: + name: azure-cred-file + key: path-windows + optional: true + - name: CSI_ENDPOINT + value: unix://{{ .Values.windows.kubelet }}\plugins\{{ .Values.driver.name }}\csi.sock + {{- if ne .Values.driver.httpsProxy "" }} + - name: HTTPS_PROXY + value: {{ .Values.driver.httpsProxy }} + {{- end }} + {{- if ne .Values.driver.httpProxy "" }} + - name: HTTP_PROXY + value: {{ .Values.driver.httpProxy }} + {{- end }} + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + imagePullPolicy: {{ .Values.image.pullPolicy }} + volumes: + - name: plugin-dir + hostPath: + path: {{ .Values.windows.kubelet }}\plugins\{{ .Values.driver.name }}\ + type: DirectoryOrCreate +{{- end -}} diff --git a/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml b/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml index d4f6e92f2e..fdc487738d 100644 --- a/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml +++ b/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml @@ -1,4 +1,4 @@ -{{- if .Values.windows.enabled}} +{{- if and .Values.windows.enabled (not .Values.windows.hostprocess) }} kind: DaemonSet apiVersion: apps/v1 metadata: diff --git a/charts/latest/azurefile-csi-driver/values.yaml b/charts/latest/azurefile-csi-driver/values.yaml index dd10442b12..2d4b83e049 100644 --- a/charts/latest/azurefile-csi-driver/values.yaml +++ b/charts/latest/azurefile-csi-driver/values.yaml @@ -214,6 +214,7 @@ linux: windows: enabled: true + hostprocess: false dsName: csi-azurefile-node-win # daemonset name kubelet: 'C:\var\lib\kubelet' kubeconfig: "" diff --git a/deploy/csi-azurefile-node-windows-hostprocess.yaml b/deploy/csi-azurefile-node-windows-hostprocess.yaml new file mode 100644 index 0000000000..20e4794980 --- /dev/null +++ b/deploy/csi-azurefile-node-windows-hostprocess.yaml @@ -0,0 +1,125 @@ +--- +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: csi-azurefile-node-win + namespace: kube-system +spec: + updateStrategy: + rollingUpdate: + maxUnavailable: 1 + type: RollingUpdate + selector: + matchLabels: + app: csi-azurefile-node-win + template: + metadata: + labels: + app: csi-azurefile-node-win + spec: + serviceAccountName: csi-azurefile-node-sa + tolerations: + - key: "node.kubernetes.io/os" + operator: "Exists" + effect: "NoSchedule" + nodeSelector: + kubernetes.io/os: windows + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: type + operator: NotIn + values: + - virtual-kubelet + priorityClassName: system-node-critical + securityContext: + windowsOptions: + hostProcess: true + runAsUserName: "NT AUTHORITY\\SYSTEM" + hostNetwork: true + containers: + - name: liveness-probe + image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.7.0 + command: + - "livenessprobe.exe" + args: + - --csi-address=$(CSI_ENDPOINT) + - --probe-timeout=3s + - --health-port=29613 + - --v=2 + env: + - name: CSI_ENDPOINT + value: unix://C:\\var\\lib\\kubelet\\plugins\\file.csi.azure.com\\csi.sock + - name: node-driver-registrar + image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.5.1 + command: + - "csi-node-driver-registrar.exe" + args: + - "--v=2" + - "--csi-address=$(CSI_ENDPOINT)" + - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" + - "--plugin-registration-path=$(PLUGIN_REG_DIR)" + livenessProbe: + exec: + command: + - /csi-node-driver-registrar.exe + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --mode=kubelet-registration-probe + initialDelaySeconds: 60 + timeoutSeconds: 30 + env: + - name: CSI_ENDPOINT + value: unix://C:\\var\\lib\\kubelet\\plugins\\file.csi.azure.com\\csi.sock + - name: DRIVER_REG_SOCK_PATH + value: C:\\var\\lib\\kubelet\\plugins\\file.csi.azure.com\\csi.sock + - name: PLUGIN_REG_DIR + value: C:\\var\\lib\\kubelet\\plugins_registry\\ + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: azurefile + image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest-windows-hp + imagePullPolicy: Always + command: + - "azurefileplugin.exe" + args: + - --v=5 + - --endpoint=$(CSI_ENDPOINT) + - --nodeid=$(KUBE_NODE_NAME) + - --kubeconfig=C:\\k\\config + - --metrics-address=0.0.0.0:29615 + - --enable-windows-host-process=true + ports: + - containerPort: 29613 + name: healthz + protocol: TCP + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + timeoutSeconds: 10 + periodSeconds: 30 + env: + - name: AZURE_CREDENTIAL_FILE + valueFrom: + configMapKeyRef: + name: azure-cred-file + key: path-windows + optional: true + - name: CSI_ENDPOINT + value: unix://C:\\var\\lib\\kubelet\\plugins\\file.csi.azure.com\\csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + volumes: + - name: plugin-dir + hostPath: + path: C:\var\lib\kubelet\plugins\file.csi.azure.com\ + type: DirectoryOrCreate diff --git a/deploy/install-driver.sh b/deploy/install-driver.sh index f18c927fc4..7f8f214878 100755 --- a/deploy/install-driver.sh +++ b/deploy/install-driver.sh @@ -14,6 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# using example: ./install-driver.sh [local|master|any remote branch] [snapshot,hostprocess] + set -euo pipefail ver="master" @@ -39,7 +41,8 @@ kubectl apply -f $repo/rbac-csi-azurefile-node.yaml kubectl apply -f $repo/csi-azurefile-controller.yaml kubectl apply -f $repo/csi-azurefile-driver.yaml kubectl apply -f $repo/csi-azurefile-node.yaml -kubectl apply -f $repo/csi-azurefile-node-windows.yaml + +windowsMode="csi-proxy" if [[ "$#" -gt 1 ]]; then if [[ "$2" == *"snapshot"* ]]; then @@ -48,5 +51,17 @@ if [[ "$#" -gt 1 ]]; then kubectl apply -f $repo/rbac-csi-snapshot-controller.yaml kubectl apply -f $repo/csi-snapshot-controller.yaml fi + + if [[ "$2" == *"hostprocess"* ]]; then + echo "deploy windows driver with hostprocess ..." + windowsMode="hostProcess" + kubectl apply -f $repo/csi-azurefile-node-windows-hostprocess.yaml + fi fi + +if [[ "$windowsMode" == *"csi-proxy"* ]]; then + echo "deploy windows pods with csi-proxy ..." + kubectl apply -f $repo/csi-azurefile-node-windows.yaml +fi + echo 'Azure File CSI driver installed successfully.' diff --git a/deploy/uninstall-driver.sh b/deploy/uninstall-driver.sh index 8b0ad9c0a6..d30f272d75 100755 --- a/deploy/uninstall-driver.sh +++ b/deploy/uninstall-driver.sh @@ -38,6 +38,7 @@ kubectl delete -f $repo/csi-snapshot-controller.yaml --ignore-not-found kubectl delete -f $repo/csi-azurefile-controller.yaml --ignore-not-found kubectl delete -f $repo/csi-azurefile-node.yaml --ignore-not-found kubectl delete -f $repo/csi-azurefile-node-windows.yaml --ignore-not-found +kubectl delete -f $repo/csi-azurefile-node-windows-hostprocess.yaml --ignore-not-found kubectl delete -f $repo/csi-azurefile-driver.yaml --ignore-not-found kubectl delete -f $repo/crd-csi-snapshot.yaml --ignore-not-found kubectl delete -f $repo/rbac-csi-snapshot-controller.yaml --ignore-not-found From bdd9fd3e5008310a25e2c24bf70d5b4b6ecdc68e Mon Sep 17 00:00:00 2001 From: Ji An Liu Date: Fri, 10 Feb 2023 03:13:11 +0000 Subject: [PATCH 075/109] build windows host-process based image Signed-off-by: Ji An Liu update chart file --- Makefile | 13 +++- charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 12111 -> 12159 bytes ...si-azurefile-node-windows-hostprocess.yaml | 31 +++++----- ...si-azurefile-node-windows-hostprocess.yaml | 31 +++++----- pkg/azurefile/azure.go | 56 ++++++++++++++++-- pkg/azurefile/azure_test.go | 32 +++++++++- pkg/azurefile/azurefile.go | 2 +- .../WindowsHostProcess.Dockerfile | 9 +++ 8 files changed, 137 insertions(+), 37 deletions(-) create mode 100644 pkg/azurefileplugin/WindowsHostProcess.Dockerfile diff --git a/Makefile b/Makefile index 6534021b39..faf20471dd 100755 --- a/Makefile +++ b/Makefile @@ -95,12 +95,16 @@ e2e-test: go test -v -timeout=0 ./test/e2e ${GINKGO_FLAGS};\ fi -# In the scenario "host-process" and "csi-proxy", use the same daemonset name. +# In the scenario "host-process" and "csi-proxy", use the same daemonset name. # The command "helm install" would validate if the name is duplicated and return error or not. # So here we have to use flag "--disable-openapi-validation" to skip the validation. .PHONY: e2e-bootstrap e2e-bootstrap: install-helm +ifdef WINDOWS_USE_HOST_PROCESS_CONTAINERS + (docker pull $(CSI_IMAGE_TAG) && docker pull $(CSI_IMAGE_TAG)-windows-hp) || make container-all push-manifest +else docker pull $(CSI_IMAGE_TAG) || make container-all push-manifest +endif ifdef TEST_WINDOWS ifdef WINDOWS_USE_HOST_PROCESS_CONTAINERS helm install azurefile-csi-driver charts/latest/azurefile-csi-driver --namespace kube-system --wait --timeout=15m -v=5 --debug \ @@ -169,6 +173,12 @@ container-windows: --provenance=false --sbom=false \ --build-arg ARCH=${ARCH} -f ./pkg/azurefileplugin/Windows.Dockerfile . +# Set --provenance=false to not generate the provenance (which is what causes the multi-platform index to be generated, even for a single platform). +.PHONY: container-windows-hostprocess +container-windows-hostprocess: + docker buildx build --pull --output=type=$(OUTPUT_TYPE) --platform="windows/$(ARCH)" --provenance=false --sbom=false \ + -t $(CSI_IMAGE_TAG)-windows-hp -f ./pkg/azurefileplugin/WindowsHostProcess.Dockerfile . + .PHONY: container-all container-all: azurefile-windows docker buildx rm container-builder || true @@ -184,6 +194,7 @@ container-all: azurefile-windows for osversion in $(ALL_OSVERSIONS.windows); do \ OSVERSION=$${osversion} $(MAKE) container-windows; \ done + $(MAKE) container-windows-hostprocess .PHONY: push-manifest push-manifest: diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz index 8a8beae63121163247daa7ac13ee6678716f71ba..2f567f18e617c231662b2a86ca28d2c3bf864302 100644 GIT binary patch delta 11919 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 delta 11895 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 Vy*>aaC@2WT=g*}+)EqR_{|BMeYoh=F diff --git a/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml b/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml index 866915e8ea..3414bf8774 100644 --- a/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml +++ b/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml @@ -62,6 +62,23 @@ spec: hostProcess: true runAsUserName: "NT AUTHORITY\\SYSTEM" hostNetwork: true + initContainers: + - name: init +{{- if hasPrefix "/" .Values.image.livenessProbe.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- else }} + image: "{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- end }} + imagePullPolicy: {{ .Values.image.livenessProbe.pullPolicy }} + command: + - "powershell.exe" + - "-c" + - "New-Item" + - "-ItemType" + - "Directory" + - "-Path" + - "C:\\var\\lib\\kubelet\\plugins\\{{ .Values.driver.name }}\\" + - "-Force" containers: - name: liveness-probe {{- if hasPrefix "/" .Values.image.livenessProbe.repository }} @@ -94,14 +111,6 @@ spec: - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" - "--plugin-registration-path=$(PLUGIN_REG_DIR)" - "--v=2" - livenessProbe: - exec: - command: - - csi-node-driver-registrar.exe - - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) - - --mode=kubelet-registration-probe - initialDelaySeconds: 60 - timeoutSeconds: 30 env: - name: CSI_ENDPOINT value: unix://{{ .Values.windows.kubelet }}\plugins\{{ .Values.driver.name }}\csi.sock @@ -127,7 +136,6 @@ spec: - "--v={{ .Values.node.logLevel }}" - "--endpoint=$(CSI_ENDPOINT)" - "--nodeid=$(KUBE_NODE_NAME)" - - "--metrics-address=0.0.0.0:{{ .Values.node.metricsPort }}" - "--kubeconfig={{ .Values.windows.kubeconfig }}" - "--drivername={{ .Values.driver.name }}" - "--cloud-config-secret-name={{ .Values.node.cloudConfigSecretName }}" @@ -172,9 +180,4 @@ spec: apiVersion: v1 fieldPath: spec.nodeName imagePullPolicy: {{ .Values.image.pullPolicy }} - volumes: - - name: plugin-dir - hostPath: - path: {{ .Values.windows.kubelet }}\plugins\{{ .Values.driver.name }}\ - type: DirectoryOrCreate {{- end -}} diff --git a/deploy/csi-azurefile-node-windows-hostprocess.yaml b/deploy/csi-azurefile-node-windows-hostprocess.yaml index 20e4794980..c2714f57c5 100644 --- a/deploy/csi-azurefile-node-windows-hostprocess.yaml +++ b/deploy/csi-azurefile-node-windows-hostprocess.yaml @@ -39,9 +39,23 @@ spec: hostProcess: true runAsUserName: "NT AUTHORITY\\SYSTEM" hostNetwork: true + initContainers: + - name: init + image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.7.0 + imagePullPolicy: IfNotPresent + command: + - "powershell.exe" + - "-c" + - "New-Item" + - "-ItemType" + - "Directory" + - "-Path" + - "C:\\var\\lib\\kubelet\\plugins\\{{ .Values.driver.name }}\\" + - "-Force" containers: - name: liveness-probe image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.7.0 + imagePullPolicy: IfNotPresent command: - "livenessprobe.exe" args: @@ -54,6 +68,7 @@ spec: value: unix://C:\\var\\lib\\kubelet\\plugins\\file.csi.azure.com\\csi.sock - name: node-driver-registrar image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.5.1 + imagePullPolicy: IfNotPresent command: - "csi-node-driver-registrar.exe" args: @@ -61,14 +76,6 @@ spec: - "--csi-address=$(CSI_ENDPOINT)" - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" - "--plugin-registration-path=$(PLUGIN_REG_DIR)" - livenessProbe: - exec: - command: - - /csi-node-driver-registrar.exe - - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) - - --mode=kubelet-registration-probe - initialDelaySeconds: 60 - timeoutSeconds: 30 env: - name: CSI_ENDPOINT value: unix://C:\\var\\lib\\kubelet\\plugins\\file.csi.azure.com\\csi.sock @@ -82,7 +89,7 @@ spec: fieldPath: spec.nodeName - name: azurefile image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest-windows-hp - imagePullPolicy: Always + imagePullPolicy: IfNotPresent command: - "azurefileplugin.exe" args: @@ -90,7 +97,6 @@ spec: - --endpoint=$(CSI_ENDPOINT) - --nodeid=$(KUBE_NODE_NAME) - --kubeconfig=C:\\k\\config - - --metrics-address=0.0.0.0:29615 - --enable-windows-host-process=true ports: - containerPort: 29613 @@ -118,8 +124,3 @@ spec: fieldRef: apiVersion: v1 fieldPath: spec.nodeName - volumes: - - name: plugin-dir - hostPath: - path: C:\var\lib\kubelet\plugins\file.csi.azure.com\ - type: DirectoryOrCreate diff --git a/pkg/azurefile/azure.go b/pkg/azurefile/azure.go index 9df79777ae..4b1a399d14 100644 --- a/pkg/azurefile/azure.go +++ b/pkg/azurefile/azure.go @@ -20,7 +20,9 @@ import ( "context" "errors" "fmt" + "net" "os" + "path/filepath" "runtime" "strings" @@ -29,6 +31,7 @@ import ( clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + certutil "k8s.io/client-go/util/cert" "k8s.io/klog/v2" azure "sigs.k8s.io/cloud-provider-azure/pkg/provider" @@ -45,7 +48,7 @@ var ( ) // getCloudProvider get Azure Cloud Provider -func getCloudProvider(kubeconfig, nodeID, secretName, secretNamespace, userAgent string, allowEmptyCloudConfig bool, kubeAPIQPS float64, kubeAPIBurst int) (*azure.Cloud, error) { +func getCloudProvider(kubeconfig, nodeID, secretName, secretNamespace, userAgent string, allowEmptyCloudConfig, enableWindowsHostProcess bool, kubeAPIQPS float64, kubeAPIBurst int) (*azure.Cloud, error) { var ( config *azure.Config kubeClient *clientset.Clientset @@ -60,7 +63,7 @@ func getCloudProvider(kubeconfig, nodeID, secretName, secretNamespace, userAgent }, } - kubeCfg, err := getKubeConfig(kubeconfig) + kubeCfg, err := getKubeConfig(kubeconfig, enableWindowsHostProcess) if err == nil && kubeCfg != nil { klog.V(2).Infof("set QPS(%f) and QPS Burst(%d) for driver kubeClient", float32(kubeAPIQPS), kubeAPIBurst) kubeCfg.QPS = float32(kubeAPIQPS) @@ -148,13 +151,13 @@ func getCloudProvider(kubeconfig, nodeID, secretName, secretNamespace, userAgent return az, nil } -func getKubeConfig(kubeconfig string) (config *rest.Config, err error) { +func getKubeConfig(kubeconfig string, enableWindowsHostProcess bool) (config *rest.Config, err error) { if kubeconfig != "" { if config, err = clientcmd.BuildConfigFromFlags("", kubeconfig); err != nil { return nil, err } } else { - if config, err = rest.InClusterConfig(); err != nil { + if config, err = inClusterConfig(enableWindowsHostProcess); err != nil { return nil, err } } @@ -227,3 +230,48 @@ func (d *Driver) updateSubnetServiceEndpoints(ctx context.Context, vnetResourceG return nil } + +// inClusterConfig is copied from https://github.com/kubernetes/client-go/blob/b46677097d03b964eab2d67ffbb022403996f4d4/rest/config.go#L507-L541 +// When using Windows HostProcess containers, the path "/var/run/secrets/kubernetes.io/serviceaccount/" is under host, not container. +// Then the token and ca.crt files would be not found. +// An environment variable $CONTAINER_SANDBOX_MOUNT_POINT is set upon container creation and provides the absolute host path to the container volume. +// See https://kubernetes.io/docs/tasks/configure-pod-container/create-hostprocess-pod/#volume-mounts for more details. +func inClusterConfig(enableWindowsHostProcess bool) (*rest.Config, error) { + var ( + tokenFile = "/var/run/secrets/kubernetes.io/serviceaccount/token" + rootCAFile = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" + ) + if enableWindowsHostProcess { + containerSandboxMountPath := os.Getenv("CONTAINER_SANDBOX_MOUNT_POINT") + if len(containerSandboxMountPath) == 0 { + return nil, errors.New("unable to load in-cluster configuration, containerSandboxMountPath must be defined") + } + tokenFile = filepath.Join(containerSandboxMountPath, tokenFile) + rootCAFile = filepath.Join(containerSandboxMountPath, rootCAFile) + } + + host, port := os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT") + if len(host) == 0 || len(port) == 0 { + return nil, rest.ErrNotInCluster + } + + token, err := os.ReadFile(tokenFile) + if err != nil { + return nil, err + } + + tlsClientConfig := rest.TLSClientConfig{} + + if _, err := certutil.NewPool(rootCAFile); err != nil { + klog.Errorf("Expected to load root CA config from %s, but got err: %v", rootCAFile, err) + } else { + tlsClientConfig.CAFile = rootCAFile + } + + return &rest.Config{ + Host: "https://" + net.JoinHostPort(host, port), + TLSClientConfig: tlsClientConfig, + BearerToken: string(token), + BearerTokenFile: tokenFile, + }, nil +} diff --git a/pkg/azurefile/azure_test.go b/pkg/azurefile/azure_test.go index a0d546e1eb..49247e2cc1 100644 --- a/pkg/azurefile/azure_test.go +++ b/pkg/azurefile/azure_test.go @@ -172,7 +172,7 @@ users: } os.Setenv(DefaultAzureCredentialFileEnv, fakeCredFile) } - cloud, err := getCloudProvider(test.kubeconfig, "", "", "", test.userAgent, test.allowEmptyCloudConfig, 5, 10) + cloud, err := getCloudProvider(test.kubeconfig, "", "", "", test.userAgent, test.allowEmptyCloudConfig, false, 5, 10) if !testutil.AssertError(err, &test.expectedErr) && !strings.Contains(err.Error(), test.expectedErr.DefaultError.Error()) { t.Errorf("desc: %s,\n input: %q, getCloudProvider err: %v, expectedErr: %v", test.desc, test.kubeconfig, err, test.expectedErr) } @@ -367,9 +367,19 @@ users: t.Error(err) } + os.Setenv("CONTAINER_SANDBOX_MOUNT_POINT", "C:\\var\\lib\\kubelet\\pods\\12345678-1234-1234-1234-123456789012") + defer os.Unsetenv("CONTAINER_SANDBOX_MOUNT_POINT") + + os.Setenv("KUBERNETES_SERVICE_HOST", "foo") + defer os.Unsetenv("KUBERNETES_SERVICE_HOST") + + os.Setenv("KUBERNETES_SERVICE_PORT", "bar") + defer os.Unsetenv("KUBERNETES_SERVICE_PORT") + tests := []struct { desc string kubeconfig string + enableWindowsHostProcess bool expectError bool envVariableHasConfig bool envVariableConfigIsValid bool @@ -377,6 +387,7 @@ users: { desc: "[success] valid kube config passed", kubeconfig: validKubeConfig, + enableWindowsHostProcess: false, expectError: false, envVariableHasConfig: false, envVariableConfigIsValid: false, @@ -384,6 +395,23 @@ users: { desc: "[failure] invalid kube config passed", kubeconfig: emptyKubeConfig, + enableWindowsHostProcess: false, + expectError: true, + envVariableHasConfig: false, + envVariableConfigIsValid: false, + }, + { + desc: "[failure] invalid kube config passed", + kubeconfig: emptyKubeConfig, + enableWindowsHostProcess: false, + expectError: true, + envVariableHasConfig: false, + envVariableConfigIsValid: false, + }, + { + desc: "[failure] empty Kubeconfig under container sandbox mount path", + kubeconfig: "", + enableWindowsHostProcess: true, expectError: true, envVariableHasConfig: false, envVariableConfigIsValid: false, @@ -391,7 +419,7 @@ users: } for _, test := range tests { - _, err := getKubeConfig(test.kubeconfig) + _, err := getKubeConfig(test.kubeconfig, test.enableWindowsHostProcess) receiveError := (err != nil) if test.expectError != receiveError { t.Errorf("desc: %s,\n input: %q, GetCloudProvider err: %v, expectErr: %v", test.desc, test.kubeconfig, err, test.expectError) diff --git a/pkg/azurefile/azurefile.go b/pkg/azurefile/azurefile.go index 55ff37cc82..1cc127e1f4 100644 --- a/pkg/azurefile/azurefile.go +++ b/pkg/azurefile/azurefile.go @@ -308,7 +308,7 @@ func (d *Driver) Run(endpoint, kubeconfig string, testBool bool) { userAgent := GetUserAgent(d.Name, d.customUserAgent, d.userAgentSuffix) klog.V(2).Infof("driver userAgent: %s", userAgent) - d.cloud, err = getCloudProvider(kubeconfig, d.NodeID, d.cloudConfigSecretName, d.cloudConfigSecretNamespace, userAgent, d.allowEmptyCloudConfig, d.kubeAPIQPS, d.kubeAPIBurst) + d.cloud, err = getCloudProvider(kubeconfig, d.NodeID, d.cloudConfigSecretName, d.cloudConfigSecretNamespace, userAgent, d.allowEmptyCloudConfig, d.enableWindowsHostProcess, d.kubeAPIQPS, d.kubeAPIBurst) if err != nil { klog.Fatalf("failed to get Azure Cloud Provider, error: %v", err) } diff --git a/pkg/azurefileplugin/WindowsHostProcess.Dockerfile b/pkg/azurefileplugin/WindowsHostProcess.Dockerfile new file mode 100644 index 0000000000..04f24e71cb --- /dev/null +++ b/pkg/azurefileplugin/WindowsHostProcess.Dockerfile @@ -0,0 +1,9 @@ +FROM mcr.microsoft.com/oss/kubernetes/windows-host-process-containers-base-image:v1.0.0 +LABEL description="CSI Azure file plugin" + +ARG ARCH=amd64 +ARG binary=./_output/${ARCH}/azurefileplugin.exe +COPY ${binary} /azurefileplugin.exe +ENV PATH="C:\Windows\system32;C:\Windows;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;" +USER ContainerAdministrator +ENTRYPOINT ["/azurefileplugin.exe"] From 55c7b46ac878f730caae448033a2b5664984fead Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Mon, 8 May 2023 05:46:04 +0000 Subject: [PATCH 076/109] cleanup: remove livenessProbe in hostprocess deployment --- charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 12159 -> 12130 bytes ...si-azurefile-node-windows-hostprocess.yaml | 30 ------------------ ...si-azurefile-node-windows-hostprocess.yaml | 27 +--------------- 3 files changed, 1 insertion(+), 56 deletions(-) diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz index 2f567f18e617c231662b2a86ca28d2c3bf864302..19eada42689b7bede57ce47a4bf60fe1d4c42483 100644 GIT binary patch literal 12130 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 A3jhEB literal 12159 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 a|BZ70Z|FH7(!W`I;DBOIB*+pd$o~K_un*q= diff --git a/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml b/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml index 3414bf8774..ddf5caa391 100644 --- a/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml +++ b/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml @@ -80,24 +80,6 @@ spec: - "C:\\var\\lib\\kubelet\\plugins\\{{ .Values.driver.name }}\\" - "-Force" containers: - - name: liveness-probe -{{- if hasPrefix "/" .Values.image.livenessProbe.repository }} - image: "{{ .Values.image.baseRepo }}{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" -{{- else }} - image: "{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" -{{- end }} - command: - - "livenessprobe.exe" - args: - - "--csi-address=$(CSI_ENDPOINT)" - - "--probe-timeout=3s" - - "--health-port={{ .Values.node.livenessProbe.healthPort }}" - - "--v=2" - env: - - name: CSI_ENDPOINT - value: unix://{{ .Values.windows.kubelet }}\plugins\{{ .Values.driver.name }}\csi.sock - imagePullPolicy: {{ .Values.image.livenessProbe.pullPolicy }} - resources: {{- toYaml .Values.windows.resources.livenessProbe | nindent 12 }} - name: node-driver-registrar {{- if hasPrefix "/" .Values.image.nodeDriverRegistrar.repository }} image: "{{ .Values.image.baseRepo }}{{ .Values.image.nodeDriverRegistrar.repository }}:{{ .Values.image.nodeDriverRegistrar.tag }}" @@ -145,18 +127,6 @@ spec: - "--allow-empty-cloud-config={{ .Values.node.allowEmptyCloudConfig }}" - "--enable-get-volume-stats={{ .Values.feature.enableGetVolumeStats }}" - "--enable-windows-host-process=true" - ports: - - containerPort: {{ .Values.node.livenessProbe.healthPort }} - name: healthz - protocol: TCP - livenessProbe: - failureThreshold: 5 - httpGet: - path: /healthz - port: healthz - initialDelaySeconds: 30 - timeoutSeconds: 10 - periodSeconds: 30 env: - name: AZURE_CREDENTIAL_FILE valueFrom: diff --git a/deploy/csi-azurefile-node-windows-hostprocess.yaml b/deploy/csi-azurefile-node-windows-hostprocess.yaml index c2714f57c5..c602ba1e56 100644 --- a/deploy/csi-azurefile-node-windows-hostprocess.yaml +++ b/deploy/csi-azurefile-node-windows-hostprocess.yaml @@ -53,21 +53,8 @@ spec: - "C:\\var\\lib\\kubelet\\plugins\\{{ .Values.driver.name }}\\" - "-Force" containers: - - name: liveness-probe - image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.7.0 - imagePullPolicy: IfNotPresent - command: - - "livenessprobe.exe" - args: - - --csi-address=$(CSI_ENDPOINT) - - --probe-timeout=3s - - --health-port=29613 - - --v=2 - env: - - name: CSI_ENDPOINT - value: unix://C:\\var\\lib\\kubelet\\plugins\\file.csi.azure.com\\csi.sock - name: node-driver-registrar - image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.5.1 + image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.10.0 imagePullPolicy: IfNotPresent command: - "csi-node-driver-registrar.exe" @@ -98,18 +85,6 @@ spec: - --nodeid=$(KUBE_NODE_NAME) - --kubeconfig=C:\\k\\config - --enable-windows-host-process=true - ports: - - containerPort: 29613 - name: healthz - protocol: TCP - livenessProbe: - failureThreshold: 5 - httpGet: - path: /healthz - port: healthz - initialDelaySeconds: 30 - timeoutSeconds: 10 - periodSeconds: 30 env: - name: AZURE_CREDENTIAL_FILE valueFrom: From ea0d561e7807f965a1417f7214bb66d060a4ece1 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Mon, 8 May 2023 07:22:36 +0000 Subject: [PATCH 077/109] fix: NewSmbLink failure --- pkg/os/smb/smb.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/os/smb/smb.go b/pkg/os/smb/smb.go index 625dbb019e..76300eec9a 100644 --- a/pkg/os/smb/smb.go +++ b/pkg/os/smb/smb.go @@ -54,7 +54,7 @@ func NewSmbLink(remotePath, localPath string) error { cmdLine := `New-Item -ItemType SymbolicLink $Env:smblocalPath -Target $Env:smbremotepath` cmd := exec.Command("powershell", "/c", cmdLine) - cmd.Env = append(os.Environ(), "smbremotepath="+remotePath, "smblocalpath=%s"+localPath) + cmd.Env = append(os.Environ(), fmt.Sprintf("smbremotepath=%s", remotePath), fmt.Sprintf("smblocalpath=%s", localPath)) output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("error linking %s to %s. output: %s, err: %v", remotePath, localPath, string(output), err) From e3e1613c3bd4fac8135ab6ed83dc20ff0cafbc37 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Mon, 8 May 2023 11:47:07 +0000 Subject: [PATCH 078/109] chore: refine --- charts/README.md | 1 + charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 12130 -> 12139 bytes ...si-azurefile-node-windows-hostprocess.yaml | 8 ++++---- ...si-azurefile-node-windows-hostprocess.yaml | 4 ++-- deploy/install-driver.sh | 9 +++++---- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/charts/README.md b/charts/README.md index 090d4f4d74..4c8352425d 100644 --- a/charts/README.md +++ b/charts/README.md @@ -168,6 +168,7 @@ The following table lists the configurable parameters of the latest Azure File C | `linux.resources.azurefile.requests.memory` | azurefile memory requests | 20Mi | | `windows.enabled` | whether enable windows feature | `true` | | `windows.dsName` | name of driver daemonset on windows |`csi-azurefile-node-win` | +| `windows.hostprocess` | whether deploy driver daemonset with host process containers on windows | `false` | | `windows.kubelet` | configure kubelet directory path on Windows agent node | `'C:\var\lib\kubelet'` | | `windows.kubeconfig` | configure kubeconfig path on Windows agent node | `'C:\k\config'` | | `windows.enableRegistrationProbe` | enable [kubelet-registration-probe](https://github.com/kubernetes-csi/node-driver-registrar#health-check-with-an-exec-probe) on windows driver config | `true` diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz index 19eada42689b7bede57ce47a4bf60fe1d4c42483..4d7840616b09eff236999d5b02325e71a4325dab 100644 GIT binary patch delta 11861 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 E190Sok^lez diff --git a/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml b/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml index ddf5caa391..fdb226e6a5 100644 --- a/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml +++ b/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml @@ -64,12 +64,12 @@ spec: hostNetwork: true initContainers: - name: init -{{- if hasPrefix "/" .Values.image.livenessProbe.repository }} - image: "{{ .Values.image.baseRepo }}{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" +{{- if hasPrefix "/" .Values.image.azurefile.repository }} + image: "{{ .Values.image.baseRepo }}{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}-windows-hp" {{- else }} - image: "{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" + image: "{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}-windows-hp" {{- end }} - imagePullPolicy: {{ .Values.image.livenessProbe.pullPolicy }} + imagePullPolicy: {{ .Values.image.pullPolicy }} command: - "powershell.exe" - "-c" diff --git a/deploy/csi-azurefile-node-windows-hostprocess.yaml b/deploy/csi-azurefile-node-windows-hostprocess.yaml index c602ba1e56..bc8c81f5e4 100644 --- a/deploy/csi-azurefile-node-windows-hostprocess.yaml +++ b/deploy/csi-azurefile-node-windows-hostprocess.yaml @@ -41,7 +41,7 @@ spec: hostNetwork: true initContainers: - name: init - image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.7.0 + image: mcr.microsoft.com/k8s/csi/azurefile-csi:latest-windows-hp imagePullPolicy: IfNotPresent command: - "powershell.exe" @@ -54,7 +54,7 @@ spec: - "-Force" containers: - name: node-driver-registrar - image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.10.0 + image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.8.0 imagePullPolicy: IfNotPresent command: - "csi-node-driver-registrar.exe" diff --git a/deploy/install-driver.sh b/deploy/install-driver.sh index 7f8f214878..8d5f4282d7 100755 --- a/deploy/install-driver.sh +++ b/deploy/install-driver.sh @@ -53,14 +53,15 @@ if [[ "$#" -gt 1 ]]; then fi if [[ "$2" == *"hostprocess"* ]]; then - echo "deploy windows driver with hostprocess ..." windowsMode="hostProcess" - kubectl apply -f $repo/csi-azurefile-node-windows-hostprocess.yaml fi fi -if [[ "$windowsMode" == *"csi-proxy"* ]]; then - echo "deploy windows pods with csi-proxy ..." +if [[ "$windowsMode" == *"hostprocess"* ]]; then + echo "deploy windows driver with hostprocess mode..." + kubectl apply -f $repo/csi-azurefile-node-windows-hostprocess.yaml +else + echo "deploy windows driver with csi-proxy mode ..." kubectl apply -f $repo/csi-azurefile-node-windows.yaml fi From c39fe2e6f1c699e1c02bb266daad4c3d477a39b1 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Tue, 9 May 2023 14:20:13 +0000 Subject: [PATCH 079/109] test: add dependabot --- .github/dependabot.yaml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/dependabot.yaml diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000000..b2da86fea4 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,20 @@ +version: 2 +updates: +- package-ecosystem: gomod + directory: "/" + schedule: + interval: daily + labels: + - "area/dependency" + - "release-note-none" + - "ok-to-test" + open-pull-requests-limit: 1 +- package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + labels: + - "area/dependency" + - "release-note-none" + - "ok-to-test" + open-pull-requests-limit: 1 From f77a563821792ef0f5947e9dbfbcbc67caec1802 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 02:32:05 +0000 Subject: [PATCH 080/109] build(deps): bump github/codeql-action from 1 to 2 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v1...v2) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index f961545b15..9e58073672 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -48,7 +48,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -63,4 +63,4 @@ jobs: make all - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 From 84a56e2ef920709fd595bc9706d9b6ee4875972b Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Wed, 10 May 2023 05:56:34 +0000 Subject: [PATCH 081/109] chore: fix release-image.sh on publishing windows hostprocess image --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index faf20471dd..5bf5948aba 100755 --- a/Makefile +++ b/Makefile @@ -220,14 +220,18 @@ ifdef PUBLISH done; \ done docker manifest inspect $(CSI_IMAGE_TAG_LATEST) + docker manifest create --amend $(CSI_IMAGE_TAG_LATEST)-windows-hp $(CSI_IMAGE_TAG)-windows-hp + docker manifest inspect $(CSI_IMAGE_TAG_LATEST)-windows-hp endif .PHONY: push-latest push-latest: ifdef CI docker manifest push --purge $(CSI_IMAGE_TAG_LATEST) + docker manifest push --purge $(CSI_IMAGE_TAG_LATEST)-windows-hp else docker push $(CSI_IMAGE_TAG_LATEST) + docker push $(CSI_IMAGE_TAG_LATEST)-windows-hp endif .PHONY: clean From 583699eb996ff842a7b7c1ea0ebf8f9575ee9651 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 06:05:34 +0000 Subject: [PATCH 082/109] build(deps): bump actions/setup-go from 2 to 4 Bumps [actions/setup-go](https://github.com/actions/setup-go) from 2 to 4. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v2...v4) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/darwin.yaml | 2 +- .github/workflows/linux.yaml | 2 +- .github/workflows/static.yaml | 2 +- .github/workflows/trivy.yaml | 2 +- .github/workflows/windows.yaml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 9e58073672..1c1bbf05b8 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Set up Go 1.x - uses: actions/setup-go@v2 + uses: actions/setup-go@v4 with: go-version: ^1.18 id: go diff --git a/.github/workflows/darwin.yaml b/.github/workflows/darwin.yaml index 2dd6771ac7..a75fb4eaa9 100644 --- a/.github/workflows/darwin.yaml +++ b/.github/workflows/darwin.yaml @@ -8,7 +8,7 @@ jobs: runs-on: macos-latest steps: - name: Set up Go 1.x - uses: actions/setup-go@v2 + uses: actions/setup-go@v4 with: go-version: ^1.16 id: go diff --git a/.github/workflows/linux.yaml b/.github/workflows/linux.yaml index f044d02012..b1a35eb7b9 100644 --- a/.github/workflows/linux.yaml +++ b/.github/workflows/linux.yaml @@ -12,7 +12,7 @@ jobs: steps: - name: Set up Go 1.x - uses: actions/setup-go@v2 + uses: actions/setup-go@v4 with: go-version: ^1.16 id: go diff --git a/.github/workflows/static.yaml b/.github/workflows/static.yaml index 82dc9efb09..dcb7c407e9 100644 --- a/.github/workflows/static.yaml +++ b/.github/workflows/static.yaml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Go 1.x - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: go-version: ^1.19 - uses: actions/checkout@master diff --git a/.github/workflows/trivy.yaml b/.github/workflows/trivy.yaml index 9eca2d6081..ad01f3eee8 100644 --- a/.github/workflows/trivy.yaml +++ b/.github/workflows/trivy.yaml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Go 1.x - uses: actions/setup-go@v2 + uses: actions/setup-go@v4 with: go-version: ^1.16 id: go diff --git a/.github/workflows/windows.yaml b/.github/workflows/windows.yaml index f73c5aa410..b475326ca5 100644 --- a/.github/workflows/windows.yaml +++ b/.github/workflows/windows.yaml @@ -13,7 +13,7 @@ jobs: runs-on: ${{ matrix.platform }} steps: - name: Set up Go 1.x - uses: actions/setup-go@v2 + uses: actions/setup-go@v4 with: go-version: ^1.16 id: go From 984f7b6ecd781ab8ed53e283b9a46ba72592c4a4 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Wed, 10 May 2023 08:35:57 +0000 Subject: [PATCH 083/109] fix: windows host process container deployment --- Makefile | 7 ++++++- charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 12139 -> 12133 bytes ...si-azurefile-node-windows-hostprocess.yaml | 7 +------ ...si-azurefile-node-windows-hostprocess.yaml | 7 +------ hack/release-image.sh | 2 +- 5 files changed, 9 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 5bf5948aba..8734eede2b 100755 --- a/Makefile +++ b/Makefile @@ -179,6 +179,11 @@ container-windows-hostprocess: docker buildx build --pull --output=type=$(OUTPUT_TYPE) --platform="windows/$(ARCH)" --provenance=false --sbom=false \ -t $(CSI_IMAGE_TAG)-windows-hp -f ./pkg/azurefileplugin/WindowsHostProcess.Dockerfile . +.PHONY: container-windows-hostprocess-latest +container-windows-hostprocess-latest: + docker buildx build --pull --output=type=$(OUTPUT_TYPE) --platform="windows/$(ARCH)" --provenance=false --sbom=false \ + -t $(CSI_IMAGE_TAG_LATEST)-windows-hp -f ./pkg/azurefileplugin/WindowsHostProcess.Dockerfile . + .PHONY: container-all container-all: azurefile-windows docker buildx rm container-builder || true @@ -220,7 +225,7 @@ ifdef PUBLISH done; \ done docker manifest inspect $(CSI_IMAGE_TAG_LATEST) - docker manifest create --amend $(CSI_IMAGE_TAG_LATEST)-windows-hp $(CSI_IMAGE_TAG)-windows-hp + docker manifest create --amend $(CSI_IMAGE_TAG_LATEST)-windows-hp $(CSI_IMAGE_TAG_LATEST)-windows-hp docker manifest inspect $(CSI_IMAGE_TAG_LATEST)-windows-hp endif diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz index 4d7840616b09eff236999d5b02325e71a4325dab..bccae8edc3f77ec1305e390355882f1cfbaaf65d 100644 GIT binary patch delta 12058 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 W#WST4SQG*R4Cdi(pof@*g!msda?QK| delta 12063 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 diff --git a/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml b/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml index fdb226e6a5..6d18432678 100644 --- a/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml +++ b/charts/latest/azurefile-csi-driver/templates/csi-azurefile-node-windows-hostprocess.yaml @@ -73,12 +73,7 @@ spec: command: - "powershell.exe" - "-c" - - "New-Item" - - "-ItemType" - - "Directory" - - "-Path" - - "C:\\var\\lib\\kubelet\\plugins\\{{ .Values.driver.name }}\\" - - "-Force" + - "New-Item -ItemType Directory -Path C:\\var\\lib\\kubelet\\plugins\\{{ .Values.driver.name }}\\ -Force" containers: - name: node-driver-registrar {{- if hasPrefix "/" .Values.image.nodeDriverRegistrar.repository }} diff --git a/deploy/csi-azurefile-node-windows-hostprocess.yaml b/deploy/csi-azurefile-node-windows-hostprocess.yaml index bc8c81f5e4..3ca6921856 100644 --- a/deploy/csi-azurefile-node-windows-hostprocess.yaml +++ b/deploy/csi-azurefile-node-windows-hostprocess.yaml @@ -46,12 +46,7 @@ spec: command: - "powershell.exe" - "-c" - - "New-Item" - - "-ItemType" - - "Directory" - - "-Path" - - "C:\\var\\lib\\kubelet\\plugins\\{{ .Values.driver.name }}\\" - - "-Force" + - "New-Item -ItemType Directory -Path C:\\var\\lib\\kubelet\\plugins\\file.csi.azure.com\\ -Force" containers: - name: node-driver-registrar image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.8.0 diff --git a/hack/release-image.sh b/hack/release-image.sh index 89f8074d96..9f083921d2 100755 --- a/hack/release-image.sh +++ b/hack/release-image.sh @@ -28,7 +28,7 @@ export CI=1 export PUBLISH=1 az acr login --name $REGISTRY_NAME -make container-all push-manifest push-latest +make container-all container-windows-hostprocess-latest push-manifest push-latest echo "sleep 60s ..." sleep 60 From e9b8bd34e4d6bc00303360a43c4b1bd6a386dbd5 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Wed, 10 May 2023 14:10:28 +0000 Subject: [PATCH 084/109] fix: add closetimeo=0 option to fix data sync issue on Ubuntu 22.04 --- pkg/azurefile/azurefile.go | 9 ++++++++- pkg/azurefile/azurefile_test.go | 18 +++++++++++++++--- pkg/azurefile/nodeserver.go | 2 +- pkg/azurefileplugin/main.go | 2 ++ 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/pkg/azurefile/azurefile.go b/pkg/azurefile/azurefile.go index 1cc127e1f4..2db1473eba 100644 --- a/pkg/azurefile/azurefile.go +++ b/pkg/azurefile/azurefile.go @@ -200,6 +200,7 @@ type DriverOptions struct { KubeAPIQPS float64 KubeAPIBurst int EnableWindowsHostProcess bool + AppendClosetimeoOption bool } // Driver implements all interfaces of CSI drivers @@ -221,6 +222,7 @@ type Driver struct { kubeAPIQPS float64 kubeAPIBurst int enableWindowsHostProcess bool + appendClosetimeoOption bool fileClient *azureFileClient mounter *mount.SafeFormatAndMount // lock per volume attach (only for vhd disk feature) @@ -268,6 +270,7 @@ func NewDriver(options *DriverOptions) *Driver { driver.kubeAPIQPS = options.KubeAPIQPS driver.kubeAPIBurst = options.KubeAPIBurst driver.enableWindowsHostProcess = options.EnableWindowsHostProcess + driver.appendClosetimeoOption = options.AppendClosetimeoOption driver.volLockMap = newLockMap() driver.subnetLockMap = newLockMap() driver.volumeLocks = newVolumeLocks() @@ -426,7 +429,7 @@ func GetFileShareInfo(id string) (string, string, string, string, string, string } // check whether mountOptions contains file_mode, dir_mode, vers, if not, append default mode -func appendDefaultMountOptions(mountOptions []string) []string { +func appendDefaultMountOptions(mountOptions []string, appendClosetimeoOption bool) []string { var defaultMountOptions = map[string]string{ fileMode: defaultFileMode, dirMode: defaultDirMode, @@ -434,6 +437,10 @@ func appendDefaultMountOptions(mountOptions []string) []string { mfsymlinks: "", } + if appendClosetimeoOption { + defaultMountOptions["sloppy,closetimeo=0"] = "" + } + // stores the mount options already included in mountOptions included := make(map[string]bool) diff --git a/pkg/azurefile/azurefile_test.go b/pkg/azurefile/azurefile_test.go index 77e2fa4360..589dc9507f 100644 --- a/pkg/azurefile/azurefile_test.go +++ b/pkg/azurefile/azurefile_test.go @@ -92,8 +92,9 @@ func TestNewFakeDriver(t *testing.T) { func TestAppendDefaultMountOptions(t *testing.T) { tests := []struct { - options []string - expected []string + options []string + appendClosetimeoOption bool + expected []string }{ { options: []string{"dir_mode=0777"}, @@ -164,10 +165,21 @@ func TestAppendDefaultMountOptions(t *testing.T) { mfsymlinks, }, }, + { + options: []string{""}, + appendClosetimeoOption: true, + expected: []string{"", fmt.Sprintf("%s=%s", + fileMode, defaultFileMode), + fmt.Sprintf("%s=%s", dirMode, defaultDirMode), + fmt.Sprintf("%s=%s", actimeo, defaultActimeo), + mfsymlinks, + "sloppy,closetimeo=0", + }, + }, } for _, test := range tests { - result := appendDefaultMountOptions(test.options) + result := appendDefaultMountOptions(test.options, test.appendClosetimeoOption) sort.Strings(result) sort.Strings(test.expected) diff --git a/pkg/azurefile/nodeserver.go b/pkg/azurefile/nodeserver.go index 3d60e75125..cc1809bee4 100644 --- a/pkg/azurefile/nodeserver.go +++ b/pkg/azurefile/nodeserver.go @@ -294,7 +294,7 @@ func (d *Driver) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRe if ephemeralVol { cifsMountFlags = util.JoinMountOptions(cifsMountFlags, strings.Split(ephemeralVolMountOptions, ",")) } - mountOptions = appendDefaultMountOptions(cifsMountFlags) + mountOptions = appendDefaultMountOptions(cifsMountFlags, d.appendClosetimeoOption) } } diff --git a/pkg/azurefileplugin/main.go b/pkg/azurefileplugin/main.go index 5c43d73bc5..963ee72a5e 100644 --- a/pkg/azurefileplugin/main.go +++ b/pkg/azurefileplugin/main.go @@ -57,6 +57,7 @@ var ( kubeAPIBurst = flag.Int("kube-api-burst", 50, "Burst to use while communicating with the kubernetes apiserver.") appendMountErrorHelpLink = flag.Bool("append-mount-error-help-link", true, "Whether to include a link for help with mount errors when a mount error occurs.") enableWindowsHostProcess = flag.Bool("enable-windows-host-process", false, "enable windows host process") + appendClosetimeoOption = flag.Bool("append-closetimeo-option", false, "Whether appending closetimeo=0 option to smb mount command") ) func main() { @@ -99,6 +100,7 @@ func handle() { KubeAPIQPS: *kubeAPIQPS, KubeAPIBurst: *kubeAPIBurst, EnableWindowsHostProcess: *enableWindowsHostProcess, + AppendClosetimeoOption: *appendClosetimeoOption, } driver := azurefile.NewDriver(&driverOptions) if driver == nil { From a84243f46c9e569e10eccbf532d2edd532f4f929 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Thu, 11 May 2023 03:38:11 +0000 Subject: [PATCH 085/109] fix: default actimeo option should respect acregmax and acdirmax --- pkg/azurefile/azurefile.go | 9 ++++----- pkg/azurefile/azurefile_test.go | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/pkg/azurefile/azurefile.go b/pkg/azurefile/azurefile.go index 1cc127e1f4..c998220911 100644 --- a/pkg/azurefile/azurefile.go +++ b/pkg/azurefile/azurefile.go @@ -443,6 +443,10 @@ func appendDefaultMountOptions(mountOptions []string) []string { included[k] = true } } + // actimeo would set both acregmax and acdirmax, so we only need to check one of them + if strings.Contains(mountOption, "acregmax") || strings.Contains(mountOption, "acdirmax") { + included[actimeo] = true + } } allMountOptions := mountOptions @@ -457,11 +461,6 @@ func appendDefaultMountOptions(mountOptions []string) []string { } } - /* todo: looks like fsGroup is not included in CSI - if !gidFlag && fsGroup != nil { - allMountOptions = append(allMountOptions, fmt.Sprintf("%s=%d", gid, *fsGroup)) - } - */ return allMountOptions } diff --git a/pkg/azurefile/azurefile_test.go b/pkg/azurefile/azurefile_test.go index 77e2fa4360..21770f6a85 100644 --- a/pkg/azurefile/azurefile_test.go +++ b/pkg/azurefile/azurefile_test.go @@ -137,6 +137,24 @@ func TestAppendDefaultMountOptions(t *testing.T) { mfsymlinks, }, }, + { + options: []string{"acregmax=1"}, + expected: []string{ + "acregmax=1", + fmt.Sprintf("%s=%s", fileMode, defaultFileMode), + fmt.Sprintf("%s=%s", dirMode, defaultDirMode), + mfsymlinks, + }, + }, + { + options: []string{"acdirmax=2"}, + expected: []string{ + "acdirmax=2", + fmt.Sprintf("%s=%s", fileMode, defaultFileMode), + fmt.Sprintf("%s=%s", dirMode, defaultDirMode), + mfsymlinks, + }, + }, { options: []string{mfsymlinks}, expected: []string{ From 21128dee873f6048aae8b91ab20e79b4b2523f03 Mon Sep 17 00:00:00 2001 From: weizhichen Date: Thu, 11 May 2023 06:34:23 +0000 Subject: [PATCH 086/109] fix docs --- docs/workload-identity.md | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/docs/workload-identity.md b/docs/workload-identity.md index a43a44b920..90637a9492 100644 --- a/docs/workload-identity.md +++ b/docs/workload-identity.md @@ -9,11 +9,7 @@ After you finish the Installation guide, you should have already: * installed the mutating admission webhook * obtained your cluster’s OIDC issuer URL -## 1. Enable Azure Workload Identity Mutating Webhook injection to Pod in the `kube-system` namespace - -Per [azure-workload-identity Known Issues](https://github.com/Azure/azure-workload-identity/blob/main/docs/book/src/known-issues.md#environment-variables-not-injected-into-pods-deployed-in-the-kube-system-namespace-in-an-aks-cluster), if you're deploying Azurefile in the `kube-system` namespace of an AKS cluster, add the `"admissions.enforcer/disabled": "true"` label or annotation in the [MutatingWebhookConfiguration](https://github.com/Azure/azure-workload-identity/blob/8644a217f09902fa1ac63e05cf04d9a3f3f1ebc3/deploy/azure-wi-webhook.yaml#L206-L235). - -## 2. Export environment variables +## 1. Export environment variables ```shell export CLUSTER_NAME="" @@ -38,7 +34,7 @@ export SA_LIST=( "csi-azurefile-controller-sa" "csi-azurefile-node-sa" ) export NAMESPACE="kube-system" ``` -## 3. Create Azurefile resource group +## 2. Create Azurefile resource group If you are using AKS, you can get the resource group where Azurefile storage class reside by running: @@ -52,7 +48,7 @@ You can also create resource group by yourself, but you must [specify the resour az group create -n $AZURE_FILE_RESOURCE_GROUP -l $LOCATION ``` -## 4. Create an AAD application or user-assigned managed identity and grant required permissions +## 3. Create an AAD application or user-assigned managed identity and grant required permissions ```shell # create an AAD application if using Azure AD Application for this tutorial @@ -61,6 +57,7 @@ az ad sp create-for-rbac --name "${APPLICATION_NAME}" ```shell # create a user-assigned managed identity if using user-assigned managed identity for this tutorial +az group create -n ${IDENTITY_RESOURCE_GROUP} -l $LOCATION az identity create --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${IDENTITY_RESOURCE_GROUP}" ``` @@ -82,7 +79,7 @@ export AZURE_FILE_RESOURCE_GROUP_ID="$(az group show -n $AZURE_FILE_RESOURCE_GRO az role assignment create --assignee $USER_ASSIGNED_IDENTITY_OBJECT_ID --role Contributor --scope $AZURE_FILE_RESOURCE_GROUP_ID ``` -## 5. Establish federated identity credential between the identity and the Azurefile service account issuer & subject +## 4. Establish federated identity credential between the identity and the Azurefile service account issuer & subject If using Azure AD Application: @@ -122,7 +119,7 @@ az identity federated-credential create \ done ``` -## 6. Deploy Azurefile +## 5. Deploy Azurefile Deploy storageclass: @@ -140,7 +137,7 @@ export CLIENT_ID="$(az ad sp list --display-name "${APPLICATION_NAME}" --query ' export TENANT_ID="$(az ad sp list --display-name "${APPLICATION_NAME}" --query '[0].appOwnerOrganizationId' -otsv)" helm install azurefile-csi-driver charts/latest/azurefile-csi-driver \ --namespace $NAMESPACE \ ---set workloadIdentity.clientID=$CLIENT_ID +--set workloadIdentity.clientID=$CLIENT_ID \ --set workloadIdentity.tenantID=$TENANT_ID ``` @@ -151,11 +148,11 @@ export CLIENT_ID="$(az identity show --name "${USER_ASSIGNED_IDENTITY_NAME}" --r export TENANT_ID="$(az identity show --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${IDENTITY_RESOURCE_GROUP}" --query 'tenantId' -otsv)" helm install azurefile-csi-driver charts/latest/azurefile-csi-driver \ --namespace $NAMESPACE \ ---set workloadIdentity.clientID=$CLIENT_ID +--set workloadIdentity.clientID=$CLIENT_ID \ --set workloadIdentity.tenantID=$TENANT_ID ``` -## 7. Deploy application using Azurefile +## 6. Deploy application using Azurefile ```shell kubectl create -f https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/deploy/example/nfs/statefulset.yaml From a6e2117eb5fc12a270cd62b670019ac5790c8496 Mon Sep 17 00:00:00 2001 From: ntishchauhan0022 Date: Thu, 11 May 2023 23:20:02 +0530 Subject: [PATCH 087/109] changing release path url --- test/external-e2e/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/external-e2e/run.sh b/test/external-e2e/run.sh index 678c5ed3b8..86ed18c664 100644 --- a/test/external-e2e/run.sh +++ b/test/external-e2e/run.sh @@ -25,7 +25,7 @@ install_ginkgo () { setup_e2e_binaries() { # download k8s external e2e binary for kubernetes - curl -sL https://storage.googleapis.com/kubernetes-release/release/v1.24.0/kubernetes-test-linux-amd64.tar.gz --output e2e-tests.tar.gz + curl -sL https://dl.k8s.io/release/v1.24.0/kubernetes-test-linux-amd64.tar.gz --output e2e-tests.tar.gz tar -xvf e2e-tests.tar.gz && rm e2e-tests.tar.gz # test on alternative driver name From bf6c9c55214468975f609662a7a9827ffb50cd67 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Fri, 12 May 2023 14:21:40 +0000 Subject: [PATCH 088/109] chore: refine windows hcp image build --- Makefile | 4 +++- hack/release-image.sh | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8734eede2b..a04a815c6a 100755 --- a/Makefile +++ b/Makefile @@ -172,6 +172,9 @@ container-windows: -t $(CSI_IMAGE_TAG)-windows-$(OSVERSION)-$(ARCH) --build-arg OSVERSION=$(OSVERSION) \ --provenance=false --sbom=false \ --build-arg ARCH=${ARCH} -f ./pkg/azurefileplugin/Windows.Dockerfile . +ifdef WINDOWS_USE_HOST_PROCESS_CONTAINERS + $(MAKE) container-windows-hostprocess +endif # Set --provenance=false to not generate the provenance (which is what causes the multi-platform index to be generated, even for a single platform). .PHONY: container-windows-hostprocess @@ -199,7 +202,6 @@ container-all: azurefile-windows for osversion in $(ALL_OSVERSIONS.windows); do \ OSVERSION=$${osversion} $(MAKE) container-windows; \ done - $(MAKE) container-windows-hostprocess .PHONY: push-manifest push-manifest: diff --git a/hack/release-image.sh b/hack/release-image.sh index 9f083921d2..9d58189335 100755 --- a/hack/release-image.sh +++ b/hack/release-image.sh @@ -26,6 +26,7 @@ export REGISTRY=$REGISTRY_NAME.azurecr.io export IMAGE_NAME=public/k8s/csi/azurefile-csi export CI=1 export PUBLISH=1 +export WINDOWS_USE_HOST_PROCESS_CONTAINERS=1 az acr login --name $REGISTRY_NAME make container-all container-windows-hostprocess-latest push-manifest push-latest From e99ab7614eb5b5a08e4bdac3eac267f0751d2634 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Sat, 13 May 2023 07:56:15 +0000 Subject: [PATCH 089/109] cleanup: update new chart versions and remove deprecated versions --- README.md | 2 +- .../v1.26.2/azurefile-csi-driver-v1.26.2.tgz | Bin 0 -> 11417 bytes .../v1.26.2/azurefile-csi-driver/Chart.yaml | 5 + .../azurefile-csi-driver/templates/NOTES.txt | 5 + .../templates/_helpers.tpl | 49 ++ .../templates/crd-csi-snapshot.yaml | 661 ++++++++++++++++++ .../templates/csi-azurefile-controller.yaml | 243 +++++++ .../templates/csi-azurefile-driver.yaml | 17 + .../templates/csi-azurefile-node-windows.yaml | 222 ++++++ .../templates/csi-azurefile-node.yaml | 217 ++++++ .../templates/csi-snapshot-controller.yaml | 65 ++ .../rbac-csi-azurefile-controller.yaml | 207 ++++++ .../templates/rbac-csi-azurefile-node.yaml | 29 + .../rbac-csi-snapshot-controller.yaml | 80 +++ ...rviceaccount-csi-azurefile-controller.yaml | 9 + .../serviceaccount-csi-azurefile-node.yaml | 9 + ...erviceaccount-csi-snapshot-controller.yaml | 9 + .../v1.26.2/azurefile-csi-driver/values.yaml | 254 +++++++ deploy/v1.26.2/crd-csi-snapshot.yaml | 659 +++++++++++++++++ deploy/v1.26.2/csi-azurefile-controller.yaml | 184 +++++ deploy/v1.26.2/csi-azurefile-driver.yaml | 15 + .../v1.26.2/csi-azurefile-node-windows.yaml | 181 +++++ deploy/v1.26.2/csi-azurefile-node.yaml | 157 +++++ deploy/v1.26.2/csi-snapshot-controller.yaml | 46 ++ .../rbac-csi-azurefile-controller.yaml | 194 +++++ deploy/v1.26.2/rbac-csi-azurefile-node.yaml | 30 + .../v1.26.2/rbac-csi-snapshot-controller.yaml | 78 +++ docs/install-azurefile-csi-driver.md | 2 +- docs/install-csi-driver-v1.26.0.md | 45 -- docs/install-csi-driver-v1.26.1.md | 45 -- ....25.0.md => install-csi-driver-v1.26.2.md} | 14 +- 31 files changed, 3634 insertions(+), 99 deletions(-) create mode 100644 charts/v1.26.2/azurefile-csi-driver-v1.26.2.tgz create mode 100644 charts/v1.26.2/azurefile-csi-driver/Chart.yaml create mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/NOTES.txt create mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/_helpers.tpl create mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/crd-csi-snapshot.yaml create mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/csi-azurefile-controller.yaml create mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/csi-azurefile-driver.yaml create mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml create mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/csi-azurefile-node.yaml create mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/csi-snapshot-controller.yaml create mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml create mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml create mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml create mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml create mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml create mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml create mode 100644 charts/v1.26.2/azurefile-csi-driver/values.yaml create mode 100644 deploy/v1.26.2/crd-csi-snapshot.yaml create mode 100644 deploy/v1.26.2/csi-azurefile-controller.yaml create mode 100644 deploy/v1.26.2/csi-azurefile-driver.yaml create mode 100644 deploy/v1.26.2/csi-azurefile-node-windows.yaml create mode 100644 deploy/v1.26.2/csi-azurefile-node.yaml create mode 100644 deploy/v1.26.2/csi-snapshot-controller.yaml create mode 100644 deploy/v1.26.2/rbac-csi-azurefile-controller.yaml create mode 100644 deploy/v1.26.2/rbac-csi-azurefile-node.yaml create mode 100644 deploy/v1.26.2/rbac-csi-snapshot-controller.yaml delete mode 100644 docs/install-csi-driver-v1.26.0.md delete mode 100644 docs/install-csi-driver-v1.26.1.md rename docs/{install-csi-driver-v1.25.0.md => install-csi-driver-v1.26.2.md} (81%) diff --git a/README.md b/README.md index 5e2299f0bd..c1d99500a2 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Disclaimer: Deploying this driver manually is not an officially supported Micros |----------------|---------------------------------------------------------- |-----------------------| |master branch |mcr.microsoft.com/k8s/csi/azurefile-csi:latest | 1.21+ | |v1.27.0 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.27.0 | 1.21+ | -|v1.26.1 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.1 | 1.21+ | +|v1.26.2 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.2 | 1.21+ | |v1.25.1 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.25.1 | 1.21+ | ### Driver parameters diff --git a/charts/v1.26.2/azurefile-csi-driver-v1.26.2.tgz b/charts/v1.26.2/azurefile-csi-driver-v1.26.2.tgz new file mode 100644 index 0000000000000000000000000000000000000000..ecf496d2c0e3b6debc62aeea9839171d01c7b343 GIT binary patch literal 11417 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 Date: Sun, 14 May 2023 09:42:09 +0000 Subject: [PATCH 090/109] fix: snapshot controller crash issue when CRDs are not ready --- charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 12133 -> 12277 bytes .../templates/csi-snapshot-controller.yaml | 9 +++++++++ deploy/csi-snapshot-controller.yaml | 9 +++++++++ 3 files changed, 18 insertions(+) diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz index bccae8edc3f77ec1305e390355882f1cfbaaf65d..41dae31a402c05e6a96d2eb48ddba4807ff10686 100644 GIT binary patch delta 12148 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 delta 12070 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 Date: Sat, 13 May 2023 11:08:43 +0000 Subject: [PATCH 091/109] feat: upgrade to snapshot v6.2.1 --- charts/README.md | 4 +- charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 12277 -> 13266 bytes .../templates/crd-csi-snapshot.yaml | 301 +++++++++++++---- .../latest/azurefile-csi-driver/values.yaml | 4 +- deploy/crd-csi-snapshot.yaml | 303 ++++++++++++++---- deploy/csi-azurefile-controller.yaml | 2 +- deploy/csi-azurefile-driver.yaml | 2 +- deploy/csi-snapshot-controller.yaml | 2 +- 8 files changed, 488 insertions(+), 130 deletions(-) diff --git a/charts/README.md b/charts/README.md index 4c8352425d..0fb465b615 100644 --- a/charts/README.md +++ b/charts/README.md @@ -128,10 +128,10 @@ The following table lists the configurable parameters of the latest Azure File C | `node.logLevel` | node driver log level |`5` | | `snapshot.enabled` | whether enable snapshot feature | `false` | | `snapshot.image.csiSnapshotter.repository` | csi-snapshotter docker image | `/oss/kubernetes-csi/csi-snapshotter` | -| `snapshot.image.csiSnapshotter.tag` | csi-snapshotter docker image tag | `v5.0.1` | +| `snapshot.image.csiSnapshotter.tag` | csi-snapshotter docker image tag | `v6.2.1` | | `snapshot.image.csiSnapshotter.pullPolicy` | csi-snapshotter image pull policy | `IfNotPresent` | | `snapshot.image.csiSnapshotController.repository` | snapshot-controller docker image | `/oss/kubernetes-csi/snapshot-controller` | -| `snapshot.image.csiSnapshotController.tag` | snapshot-controller docker image tag | `v5.0.1` | +| `snapshot.image.csiSnapshotController.tag` | snapshot-controller docker image tag | `v6.2.1` | | `snapshot.image.csiSnapshotController.pullPolicy` | snapshot-controller image pull policy | `IfNotPresent` | | `snapshot.snapshotController.name` | snapshot controller name | `csi-snapshot-controller` | | `snapshot.snapshotController.replicas` | the replicas of snapshot-controller | `2` | diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz index 41dae31a402c05e6a96d2eb48ddba4807ff10686..c44b3c3ab9d0e18fa8d27ab188754fa49213a28c 100644 GIT binary patch literal 13266 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 Q00030|36Hs_5j`i08P0t{{R30 literal 12277 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 mk1<2rzg|sJBBrOEDKwwjbDab4+$o~P?f?lft diff --git a/charts/latest/azurefile-csi-driver/templates/crd-csi-snapshot.yaml b/charts/latest/azurefile-csi-driver/templates/crd-csi-snapshot.yaml index b0e29453c5..76df8af7e9 100644 --- a/charts/latest/azurefile-csi-driver/templates/crd-csi-snapshot.yaml +++ b/charts/latest/azurefile-csi-driver/templates/crd-csi-snapshot.yaml @@ -4,8 +4,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.4.0 - api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + controller-gen.kubebuilder.io/version: v0.8.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/665" creationTimestamp: null name: volumesnapshots.snapshot.storage.k8s.io spec: @@ -24,15 +24,18 @@ spec: jsonPath: .status.readyToUse name: ReadyToUse type: boolean - - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. jsonPath: .spec.source.persistentVolumeClaimName name: SourcePVC type: string - - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. jsonPath: .spec.source.volumeSnapshotContentName name: SourceSnapshotContent type: string - - description: Represents the minimum size of volume required to rehydrate from this snapshot. + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. jsonPath: .status.restoreSize name: RestoreSize type: string @@ -40,11 +43,16 @@ spec: jsonPath: .spec.volumeSnapshotClassName name: SnapshotClass type: string - - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. jsonPath: .status.boundVolumeSnapshotContentName name: SnapshotContent type: string - - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. jsonPath: .status.creationTime name: CreationTime type: date @@ -54,51 +62,103 @@ spec: name: v1 schema: openAPIV3Schema: - description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string spec: - description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' + description: 'spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required.' properties: source: - description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. properties: persistentVolumeClaimName: - description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. type: string volumeSnapshotContentName: - description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. type: string type: object oneOf: - required: ["persistentVolumeClaimName"] - required: ["volumeSnapshotContentName"] volumeSnapshotClassName: - description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field.' type: string required: - source type: object status: - description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. properties: boundVolumeSnapshotContentName: - description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object.' type: string creationTime: - description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. format: date-time type: string error: - description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurrs during the snapshot creation. Upon success, this error field will be cleared. + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. properties: message: - description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' type: string time: description: time is the timestamp when the error was encountered. @@ -106,11 +166,27 @@ spec: type: string type: object readyToUse: - description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. type: boolean restoreSize: type: string - description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: object @@ -199,7 +275,7 @@ spec: format: date-time type: string error: - description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurrs during the snapshot creation. Upon success, this error field will be cleared. + description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurs during the snapshot creation. Upon success, this error field will be cleared. properties: message: description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' @@ -221,7 +297,7 @@ spec: required: - spec type: object - served: true + served: false storage: false subresources: status: {} @@ -231,14 +307,13 @@ status: plural: "" conditions: [] storedVersions: [] - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.4.0 - api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + controller-gen.kubebuilder.io/version: v0.8.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/665" creationTimestamp: null name: volumesnapshotclasses.snapshot.storage.k8s.io spec: @@ -257,7 +332,8 @@ spec: - jsonPath: .driver name: Driver type: string - - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + - description: Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. jsonPath: .deletionPolicy name: DeletionPolicy type: string @@ -267,27 +343,42 @@ spec: name: v1 schema: openAPIV3Schema: - description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string deletionPolicy: - description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. enum: - Delete - Retain type: string driver: - description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. type: string kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string parameters: additionalProperties: type: string - description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. type: object required: - deletionPolicy @@ -341,7 +432,7 @@ spec: - deletionPolicy - driver type: object - served: true + served: false storage: false subresources: {} status: @@ -350,14 +441,13 @@ status: plural: "" conditions: [] storedVersions: [] - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.4.0 - api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + controller-gen.kubebuilder.io/version: v0.8.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/665" creationTimestamp: null name: volumesnapshotcontents.snapshot.storage.k8s.io spec: @@ -381,11 +471,14 @@ spec: jsonPath: .status.restoreSize name: RestoreSize type: integer - - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. jsonPath: .spec.deletionPolicy name: DeletionPolicy type: string - - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. jsonPath: .spec.driver name: Driver type: string @@ -393,7 +486,8 @@ spec: jsonPath: .spec.volumeSnapshotClassName name: VolumeSnapshotClass type: string - - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. jsonPath: .spec.volumeSnapshotRef.name name: VolumeSnapshot type: string @@ -407,50 +501,102 @@ spec: name: v1 schema: openAPIV3Schema: - description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string spec: - description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. properties: deletionPolicy: - description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. enum: - Delete - Retain type: string driver: - description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. type: string source: - description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. properties: snapshotHandle: - description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. type: string volumeHandle: - description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. type: string type: object oneOf: - required: ["snapshotHandle"] - required: ["volumeHandle"] + sourceVolumeMode: + description: SourceVolumeMode is the mode of the volume whose snapshot + is taken. Can be either “Filesystem” or “Block”. If not specified, + it indicates the source volume's mode is unknown. This field is + immutable. This field is an alpha field. + type: string volumeSnapshotClassName: - description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. type: string volumeSnapshotRef: - description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. properties: apiVersion: description: API version of the referent. type: string fieldPath: - description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' type: string kind: description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' @@ -462,7 +608,8 @@ spec: description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' type: string resourceVersion: - description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' type: string uid: description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' @@ -478,14 +625,27 @@ spec: description: status represents the current information of a snapshot. properties: creationTime: - description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. format: int64 type: integer error: - description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. properties: message: - description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' type: string time: description: time is the timestamp when the error was encountered. @@ -493,15 +653,34 @@ spec: type: string type: object readyToUse: - description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. type: boolean restoreSize: - description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. format: int64 minimum: 0 type: integer snapshotHandle: - description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. type: string type: object required: @@ -648,7 +827,7 @@ spec: required: - spec type: object - served: true + served: false storage: false subresources: status: {} diff --git a/charts/latest/azurefile-csi-driver/values.yaml b/charts/latest/azurefile-csi-driver/values.yaml index 2d4b83e049..f96fea6143 100644 --- a/charts/latest/azurefile-csi-driver/values.yaml +++ b/charts/latest/azurefile-csi-driver/values.yaml @@ -133,11 +133,11 @@ snapshot: image: csiSnapshotter: repository: /oss/kubernetes-csi/csi-snapshotter - tag: v5.0.1 + tag: v6.2.1 pullPolicy: IfNotPresent csiSnapshotController: repository: /oss/kubernetes-csi/snapshot-controller - tag: v5.0.1 + tag: v6.2.1 pullPolicy: IfNotPresent snapshotController: name: csi-snapshot-controller diff --git a/deploy/crd-csi-snapshot.yaml b/deploy/crd-csi-snapshot.yaml index 18d97e6b7c..d4b90b266d 100644 --- a/deploy/crd-csi-snapshot.yaml +++ b/deploy/crd-csi-snapshot.yaml @@ -3,8 +3,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.4.0 - api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + controller-gen.kubebuilder.io/version: v0.8.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/665" creationTimestamp: null name: volumesnapshots.snapshot.storage.k8s.io spec: @@ -23,15 +23,18 @@ spec: jsonPath: .status.readyToUse name: ReadyToUse type: boolean - - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. jsonPath: .spec.source.persistentVolumeClaimName name: SourcePVC type: string - - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. jsonPath: .spec.source.volumeSnapshotContentName name: SourceSnapshotContent type: string - - description: Represents the minimum size of volume required to rehydrate from this snapshot. + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. jsonPath: .status.restoreSize name: RestoreSize type: string @@ -39,11 +42,16 @@ spec: jsonPath: .spec.volumeSnapshotClassName name: SnapshotClass type: string - - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. jsonPath: .status.boundVolumeSnapshotContentName name: SnapshotContent type: string - - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. jsonPath: .status.creationTime name: CreationTime type: date @@ -53,51 +61,103 @@ spec: name: v1 schema: openAPIV3Schema: - description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string spec: - description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' + description: 'spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required.' properties: source: - description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. properties: persistentVolumeClaimName: - description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. type: string volumeSnapshotContentName: - description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. type: string type: object oneOf: - required: ["persistentVolumeClaimName"] - required: ["volumeSnapshotContentName"] volumeSnapshotClassName: - description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field.' type: string required: - source type: object status: - description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. properties: boundVolumeSnapshotContentName: - description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object.' type: string creationTime: - description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. format: date-time type: string error: - description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurrs during the snapshot creation. Upon success, this error field will be cleared. + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. properties: message: - description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' type: string time: description: time is the timestamp when the error was encountered. @@ -105,11 +165,27 @@ spec: type: string type: object readyToUse: - description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. type: boolean restoreSize: type: string - description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: object @@ -198,7 +274,7 @@ spec: format: date-time type: string error: - description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurrs during the snapshot creation. Upon success, this error field will be cleared. + description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurs during the snapshot creation. Upon success, this error field will be cleared. properties: message: description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' @@ -220,7 +296,7 @@ spec: required: - spec type: object - served: true + served: false storage: false subresources: status: {} @@ -230,14 +306,13 @@ status: plural: "" conditions: [] storedVersions: [] - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.4.0 - api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + controller-gen.kubebuilder.io/version: v0.8.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/665" creationTimestamp: null name: volumesnapshotclasses.snapshot.storage.k8s.io spec: @@ -256,7 +331,8 @@ spec: - jsonPath: .driver name: Driver type: string - - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + - description: Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. jsonPath: .deletionPolicy name: DeletionPolicy type: string @@ -266,27 +342,42 @@ spec: name: v1 schema: openAPIV3Schema: - description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string deletionPolicy: - description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. enum: - Delete - Retain type: string driver: - description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. type: string kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string parameters: additionalProperties: type: string - description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. type: object required: - deletionPolicy @@ -340,7 +431,7 @@ spec: - deletionPolicy - driver type: object - served: true + served: false storage: false subresources: {} status: @@ -349,14 +440,13 @@ status: plural: "" conditions: [] storedVersions: [] - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.4.0 - api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" + controller-gen.kubebuilder.io/version: v0.8.0 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/665" creationTimestamp: null name: volumesnapshotcontents.snapshot.storage.k8s.io spec: @@ -380,11 +470,14 @@ spec: jsonPath: .status.restoreSize name: RestoreSize type: integer - - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. jsonPath: .spec.deletionPolicy name: DeletionPolicy type: string - - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. jsonPath: .spec.driver name: Driver type: string @@ -392,7 +485,8 @@ spec: jsonPath: .spec.volumeSnapshotClassName name: VolumeSnapshotClass type: string - - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. jsonPath: .spec.volumeSnapshotRef.name name: VolumeSnapshot type: string @@ -406,50 +500,102 @@ spec: name: v1 schema: openAPIV3Schema: - description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string spec: - description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. properties: deletionPolicy: - description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. enum: - Delete - Retain type: string driver: - description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. type: string source: - description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. properties: snapshotHandle: - description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. type: string volumeHandle: - description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. type: string type: object oneOf: - required: ["snapshotHandle"] - required: ["volumeHandle"] + sourceVolumeMode: + description: SourceVolumeMode is the mode of the volume whose snapshot + is taken. Can be either “Filesystem” or “Block”. If not specified, + it indicates the source volume's mode is unknown. This field is + immutable. This field is an alpha field. + type: string volumeSnapshotClassName: - description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. type: string volumeSnapshotRef: - description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. properties: apiVersion: description: API version of the referent. type: string fieldPath: - description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' type: string kind: description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' @@ -461,7 +607,8 @@ spec: description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' type: string resourceVersion: - description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' type: string uid: description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' @@ -477,14 +624,27 @@ spec: description: status represents the current information of a snapshot. properties: creationTime: - description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. format: int64 type: integer error: - description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. properties: message: - description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' type: string time: description: time is the timestamp when the error was encountered. @@ -492,15 +652,34 @@ spec: type: string type: object readyToUse: - description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. type: boolean restoreSize: - description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. format: int64 minimum: 0 type: integer snapshotHandle: - description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. type: string type: object required: @@ -647,7 +826,7 @@ spec: required: - spec type: object - served: true + served: false storage: false subresources: status: {} @@ -656,4 +835,4 @@ status: kind: "" plural: "" conditions: [] - storedVersions: [] \ No newline at end of file + storedVersions: [] diff --git a/deploy/csi-azurefile-controller.yaml b/deploy/csi-azurefile-controller.yaml index 99603330b9..093b2e4d76 100644 --- a/deploy/csi-azurefile-controller.yaml +++ b/deploy/csi-azurefile-controller.yaml @@ -76,7 +76,7 @@ spec: cpu: 10m memory: 20Mi - name: csi-snapshotter - image: mcr.microsoft.com/oss/kubernetes-csi/csi-snapshotter:v5.0.1 + image: mcr.microsoft.com/oss/kubernetes-csi/csi-snapshotter:v6.2.1 args: - "-v=2" - "-csi-address=$(ADDRESS)" diff --git a/deploy/csi-azurefile-driver.yaml b/deploy/csi-azurefile-driver.yaml index 55d31ed2d1..399efbbbbd 100644 --- a/deploy/csi-azurefile-driver.yaml +++ b/deploy/csi-azurefile-driver.yaml @@ -5,7 +5,7 @@ metadata: name: file.csi.azure.com annotations: csiDriver: latest - snapshot: v5.0.1 + snapshot: v6.2.1 spec: attachRequired: false podInfoOnMount: true diff --git a/deploy/csi-snapshot-controller.yaml b/deploy/csi-snapshot-controller.yaml index 3999414a28..7ab1102ee4 100644 --- a/deploy/csi-snapshot-controller.yaml +++ b/deploy/csi-snapshot-controller.yaml @@ -42,7 +42,7 @@ spec: effect: "NoSchedule" containers: - name: csi-snapshot-controller - image: mcr.microsoft.com/oss/kubernetes-csi/snapshot-controller:v5.0.1 + image: mcr.microsoft.com/oss/kubernetes-csi/snapshot-controller:v6.2.1 args: - "--v=2" - "--leader-election=true" From 81a5c9c174da0818ce039f68fa887e3b3a3097ab Mon Sep 17 00:00:00 2001 From: MartinForReal Date: Tue, 16 May 2023 14:13:34 +0800 Subject: [PATCH 092/109] build: add dependabot job for dockerfile updates. --- .github/dependabot.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index b2da86fea4..c6b2b4e03a 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -18,3 +18,14 @@ updates: - "release-note-none" - "ok-to-test" open-pull-requests-limit: 1 +- package-ecosystem: "docker" + directory: "/pkg/azurefileplugin/" + schedule: + interval: "daily" + time: "01:00" + timezone: "Asia/Shanghai" + labels: + - "area/dependency" + - "release-note-none" + - "ok-to-test" + - "kind/cleanup" From 16008719abe1661496969e86d28700e77b30bfc4 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Tue, 16 May 2023 07:27:26 +0000 Subject: [PATCH 093/109] doc: refine workload identity doc --- README.md | 3 +- docs/workload-identity.md | 60 +++++++++++++-------------------------- 2 files changed, 22 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index c1d99500a2..6221a03471 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,8 @@ This option does not depend on cloud provider config file, supports cross subscr - [NFS](./deploy/example/nfs) - [Snapshot](./deploy/example/snapshot) - [Resize](./deploy/example/resize) - + - [Workload identity](./docs/workload-identity.md) + ### Troubleshooting - [CSI driver troubleshooting guide](./docs/csi-debug.md) diff --git a/docs/workload-identity.md b/docs/workload-identity.md index 90637a9492..bed3dc9dc1 100644 --- a/docs/workload-identity.md +++ b/docs/workload-identity.md @@ -1,4 +1,8 @@ -# How to Use workload identity with Azurefile +# workload identity support +> Note: +> - supported version: v1.28.0 +> - workload identity is supported on OpenShift, capz and other self-managed clusters +> - workload identity is NOT supported on AKS **managed** Azure File CSI driver since the driver controller is managed by AKS control plane which is already using [managed identity](https://learn.microsoft.com/en-us/azure/aks/use-managed-identity) by default, it's not necessary to use workload identity for AKS managed Azure File CSI driver. ## Prerequisites @@ -29,26 +33,12 @@ export APPLICATION_NAME="" export USER_ASSIGNED_IDENTITY_NAME="" export IDENTITY_RESOURCE_GROUP="" -# Azurefile CSI Driver Service Account and namespace +# Azure File CSI driver Service Account and namespace export SA_LIST=( "csi-azurefile-controller-sa" "csi-azurefile-node-sa" ) export NAMESPACE="kube-system" ``` -## 2. Create Azurefile resource group - -If you are using AKS, you can get the resource group where Azurefile storage class reside by running: - -```shell -export AZURE_FILE_RESOURCE_GROUP="$(az aks show --name $CLUSTER_NAME --resource-group $CLUSTER_RESOURCE_GROUP --query "nodeResourceGroup" -o tsv)" -``` - -You can also create resource group by yourself, but you must [specify the resource group](https://github.com/kubernetes-sigs/azurefile-csi-driver/blob/master/docs/driver-parameters.md#:~:text=current%20k8s%20cluster-,resourceGroup,No,-if%20empty%2C%20driver) in the storage class while using Azurefile. - -```shell -az group create -n $AZURE_FILE_RESOURCE_GROUP -l $LOCATION -``` - -## 3. Create an AAD application or user-assigned managed identity and grant required permissions +## 2. Create an AAD application or user-assigned managed identity and grant required permissions ```shell # create an AAD application if using Azure AD Application for this tutorial @@ -61,9 +51,9 @@ az group create -n ${IDENTITY_RESOURCE_GROUP} -l $LOCATION az identity create --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${IDENTITY_RESOURCE_GROUP}" ``` -Grant required permission to the AAD application or user-assigned managed identity, for simplicity, we just assign Contributor role to the resource group where Azurefile storage class reside: +Grant required permission to the AAD application or user-assigned managed identity, for simplicity, we just assign Contributor role to the resource group where Azure file storage account resides: -If using Azure AD Application: + - if you are using Azure AD Application: ```shell export APPLICATION_CLIENT_ID="$(az ad sp list --display-name "${APPLICATION_NAME}" --query '[0].appId' -otsv)" @@ -71,7 +61,7 @@ export AZURE_FILE_RESOURCE_GROUP_ID="$(az group show -n $AZURE_FILE_RESOURCE_GRO az role assignment create --assignee $APPLICATION_CLIENT_ID --role Contributor --scope $AZURE_FILE_RESOURCE_GROUP_ID ``` -if using user-assigned managed identity: + - if you are using user-assigned managed identity: ```shell export USER_ASSIGNED_IDENTITY_OBJECT_ID="$(az identity show --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${IDENTITY_RESOURCE_GROUP}" --query 'principalId' -otsv)" @@ -79,9 +69,9 @@ export AZURE_FILE_RESOURCE_GROUP_ID="$(az group show -n $AZURE_FILE_RESOURCE_GRO az role assignment create --assignee $USER_ASSIGNED_IDENTITY_OBJECT_ID --role Contributor --scope $AZURE_FILE_RESOURCE_GROUP_ID ``` -## 4. Establish federated identity credential between the identity and the Azurefile service account issuer & subject +## 3. Establish federated identity credential between the identity and the Azurefile service account issuer & subject -If using Azure AD Application: + - if you are using Azure AD Application: ```shell # Get the object ID of the AAD application @@ -105,7 +95,7 @@ az ad app federated-credential create --id ${APPLICATION_OBJECT_ID} --parameters done ``` -If using user-assigned managed identity: + - if you are using user-assigned managed identity: ```shell for SERVICE_ACCOUNT_NAME in "${SA_LIST[@]}" @@ -119,18 +109,11 @@ az identity federated-credential create \ done ``` -## 5. Deploy Azurefile +## 4. Install CSI driver manually + > workload identity is NOT supported on AKS **managed** Azure File CSI driver + > if you are using AKS, please disable the managed Azure File CSI driver by `--disable-file-driver` first -Deploy storageclass: - -```shell -kubectl create -f https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/deploy/example/storageclass-azurefile-csi.yaml -kubectl create -f https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/deploy/example/storageclass-azurefile-nfs.yaml -``` - -Deploy Azurefile(If you are using AKS, please disable the managed Azurefile CSI driver by `--disable-file-driver` first) - -If using Azure AD Application: + - if you are using Azure AD Application: ```shell export CLIENT_ID="$(az ad sp list --display-name "${APPLICATION_NAME}" --query '[0].appId' -otsv)" @@ -141,7 +124,7 @@ helm install azurefile-csi-driver charts/latest/azurefile-csi-driver \ --set workloadIdentity.tenantID=$TENANT_ID ``` -If using user-assigned managed identity: + - if you are using user-assigned managed identity: ```shell export CLIENT_ID="$(az identity show --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${IDENTITY_RESOURCE_GROUP}" --query 'clientId' -otsv)" @@ -152,11 +135,8 @@ helm install azurefile-csi-driver charts/latest/azurefile-csi-driver \ --set workloadIdentity.tenantID=$TENANT_ID ``` -## 6. Deploy application using Azurefile - +## 5. Deploy application using CSI driver volume ```shell +kubectl create -f https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/deploy/example/storageclass-azurefile-csi.yaml kubectl create -f https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/deploy/example/nfs/statefulset.yaml -kubectl create -f https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/deploy/example/deployment.yaml ``` - -Please make sure all the Pods are running. From 1a0513642b17a560fc0bc6c890b321a1062f1ad6 Mon Sep 17 00:00:00 2001 From: Andy Zhang Date: Tue, 16 May 2023 21:26:35 +0800 Subject: [PATCH 094/109] Update workload-identity.md --- docs/workload-identity.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/docs/workload-identity.md b/docs/workload-identity.md index bed3dc9dc1..fb3ed5e99e 100644 --- a/docs/workload-identity.md +++ b/docs/workload-identity.md @@ -6,12 +6,7 @@ ## Prerequisites -This document is mainly refer to [Azure AD Workload Identity Quick Start](https://azure.github.io/azure-workload-identity/docs/quick-start.html). Please Complete the [Installation guide](https://azure.github.io/azure-workload-identity/docs/installation.html) before the following steps. - -After you finish the Installation guide, you should have already: - -* installed the mutating admission webhook -* obtained your cluster’s OIDC issuer URL +Before proceeding with the following steps, please ensure that you have completed the [Installation guide](https://azure.github.io/azure-workload-identity/docs/installation.html). Once you have completed the Installation guide, you should have already installed the mutating admission webhook and obtained your cluster's OIDC issuer URL. ## 1. Export environment variables @@ -69,7 +64,7 @@ export AZURE_FILE_RESOURCE_GROUP_ID="$(az group show -n $AZURE_FILE_RESOURCE_GRO az role assignment create --assignee $USER_ASSIGNED_IDENTITY_OBJECT_ID --role Contributor --scope $AZURE_FILE_RESOURCE_GROUP_ID ``` -## 3. Establish federated identity credential between the identity and the Azurefile service account issuer & subject +## 3. Establish federated identity credential between the identity and the Azurefile service account issuer and subject - if you are using Azure AD Application: From 82c7cc168cd1d7c3df17fafe869570e87883740c Mon Sep 17 00:00:00 2001 From: Andy Zhang Date: Tue, 16 May 2023 21:27:44 +0800 Subject: [PATCH 095/109] Update workload-identity.md --- docs/workload-identity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/workload-identity.md b/docs/workload-identity.md index fb3ed5e99e..1da2bbd413 100644 --- a/docs/workload-identity.md +++ b/docs/workload-identity.md @@ -6,7 +6,7 @@ ## Prerequisites -Before proceeding with the following steps, please ensure that you have completed the [Installation guide](https://azure.github.io/azure-workload-identity/docs/installation.html). Once you have completed the Installation guide, you should have already installed the mutating admission webhook and obtained your cluster's OIDC issuer URL. +Before proceeding with the following steps, please ensure that you have completed the [Installation guide](https://azure.github.io/azure-workload-identity/docs/installation.html). After completing the installation, you should have already installed the mutating admission webhook and obtained the OIDC issuer URL for your cluster. ## 1. Export environment variables From baaa2f5655cce7868d8a1200babfeda8f9c50ac7 Mon Sep 17 00:00:00 2001 From: Andy Zhang Date: Tue, 16 May 2023 21:39:48 +0800 Subject: [PATCH 096/109] Update workload-identity.md --- docs/workload-identity.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/workload-identity.md b/docs/workload-identity.md index 1da2bbd413..52ed2fbbc2 100644 --- a/docs/workload-identity.md +++ b/docs/workload-identity.md @@ -36,12 +36,12 @@ export NAMESPACE="kube-system" ## 2. Create an AAD application or user-assigned managed identity and grant required permissions ```shell -# create an AAD application if using Azure AD Application for this tutorial +# create an AAD application if you are using Azure AD Application az ad sp create-for-rbac --name "${APPLICATION_NAME}" ``` ```shell -# create a user-assigned managed identity if using user-assigned managed identity for this tutorial +# create a user-assigned managed identity if you are using user-assigned managed identity az group create -n ${IDENTITY_RESOURCE_GROUP} -l $LOCATION az identity create --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${IDENTITY_RESOURCE_GROUP}" ``` From 2c69d56044175a501bb8287e93a3f2a7a8746226 Mon Sep 17 00:00:00 2001 From: Andy Zhang Date: Tue, 16 May 2023 21:41:34 +0800 Subject: [PATCH 097/109] Update workload-identity.md --- docs/workload-identity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/workload-identity.md b/docs/workload-identity.md index 52ed2fbbc2..0969bb1861 100644 --- a/docs/workload-identity.md +++ b/docs/workload-identity.md @@ -8,7 +8,7 @@ Before proceeding with the following steps, please ensure that you have completed the [Installation guide](https://azure.github.io/azure-workload-identity/docs/installation.html). After completing the installation, you should have already installed the mutating admission webhook and obtained the OIDC issuer URL for your cluster. -## 1. Export environment variables +## 1. Set environment variables ```shell export CLUSTER_NAME="" From b3e2eaa14d925137e6f9fbf94cbac6c709cc36e6 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Thu, 18 May 2023 09:34:21 +0000 Subject: [PATCH 098/109] chore: update windows host process lib --- pkg/os/filesystem/filesystem.go | 7 +++---- pkg/os/smb/smb.go | 36 ++++++++++++--------------------- pkg/util/util.go | 15 ++++++++++++++ 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/pkg/os/filesystem/filesystem.go b/pkg/os/filesystem/filesystem.go index 0db89d8552..d2cf1ee2d9 100644 --- a/pkg/os/filesystem/filesystem.go +++ b/pkg/os/filesystem/filesystem.go @@ -20,7 +20,6 @@ import ( "context" "fmt" "os" - "os/exec" "regexp" "strings" @@ -88,9 +87,9 @@ func PathExists(ctx context.Context, request *PathExistsRequest) (bool, error) { } func PathValid(ctx context.Context, path string) (bool, error) { - cmd := exec.Command("powershell", "/c", `Test-Path $Env:remotepath`) - cmd.Env = append(os.Environ(), fmt.Sprintf("remotepath=%s", path)) - output, err := cmd.CombinedOutput() + cmd := `Test-Path $Env:remotepath` + cmdEnv := fmt.Sprintf("remotepath=%s", path) + output, err := util.RunPowershellCmd(cmd, cmdEnv) if err != nil { return false, fmt.Errorf("returned output: %s, error: %v", string(output), err) } diff --git a/pkg/os/smb/smb.go b/pkg/os/smb/smb.go index 76300eec9a..414b96b18b 100644 --- a/pkg/os/smb/smb.go +++ b/pkg/os/smb/smb.go @@ -18,17 +18,15 @@ package smb import ( "fmt" - "os" - "os/exec" "strings" + + "sigs.k8s.io/azurefile-csi-driver/pkg/util" ) func IsSmbMapped(remotePath string) (bool, error) { - cmdLine := `$(Get-SmbGlobalMapping -RemotePath $Env:smbremotepath -ErrorAction Stop).Status` - cmd := exec.Command("powershell", "/c", cmdLine) - cmd.Env = append(os.Environ(), "smbremotepath="+remotePath) - - out, err := cmd.CombinedOutput() + cmdLine := `$(Get-SmbGlobalMapping -RemotePath $Env:smbremotepath -ErrorAction Stop).Status ` + cmdEnv := fmt.Sprintf("smbremotepath=%s", remotePath) + out, err := util.RunPowershellCmd(cmdLine, cmdEnv) if err != nil { return false, fmt.Errorf("error checking smb mapping. cmd %s, output: %s, err: %v", remotePath, string(out), err) } @@ -45,6 +43,7 @@ func IsSmbMapped(remotePath string) (bool, error) { // this operation with powershell commandlet creating an directory softlink. // Since os.Symlink is currently being used in working code paths, no attempt is made in // alpha to merge the paths. +// TODO (for beta release): Merge the link paths - os.Symlink and Powershell link path. func NewSmbLink(remotePath, localPath string) error { if !strings.HasSuffix(remotePath, "\\") { // Golang has issues resolving paths mapped to file shares if they do not end in a trailing \ @@ -53,9 +52,7 @@ func NewSmbLink(remotePath, localPath string) error { } cmdLine := `New-Item -ItemType SymbolicLink $Env:smblocalPath -Target $Env:smbremotepath` - cmd := exec.Command("powershell", "/c", cmdLine) - cmd.Env = append(os.Environ(), fmt.Sprintf("smbremotepath=%s", remotePath), fmt.Sprintf("smblocalpath=%s", localPath)) - output, err := cmd.CombinedOutput() + output, err := util.RunPowershellCmd(cmdLine, fmt.Sprintf("smbremotepath=%s", remotePath), fmt.Sprintf("smblocalpath=%s", localPath)) if err != nil { return fmt.Errorf("error linking %s to %s. output: %s, err: %v", remotePath, localPath, string(output), err) } @@ -64,30 +61,23 @@ func NewSmbLink(remotePath, localPath string) error { } func NewSmbGlobalMapping(remotePath, username, password string) error { - // use PowerShell Environment Variables to store user input string to prevent command line injection // https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_environment_variables?view=powershell-5.1 cmdLine := fmt.Sprintf(`$PWord = ConvertTo-SecureString -String $Env:smbpassword -AsPlainText -Force` + `;$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Env:smbuser, $PWord` + - `;New-SmbGlobalMapping -RemotePath $Env:smbremotepath -Credential $Credential`) + `;New-SmbGlobalMapping -RemotePath $Env:smbremotepath -Credential $Credential -RequirePrivacy $true`) - cmd := exec.Command("powershell", "/c", cmdLine) - cmd.Env = append(os.Environ(), - fmt.Sprintf("smbuser=%s", username), + if output, err := util.RunPowershellCmd(cmdLine, fmt.Sprintf("smbuser=%s", username), fmt.Sprintf("smbpassword=%s", password), - fmt.Sprintf("smbremotepath=%s", remotePath)) - - if output, err := cmd.CombinedOutput(); err != nil { - return fmt.Errorf("NewSmbGlobalMapping failed. output: %q, err: %v\n[debug]smbuser=%s,smbpassword=%s,smbremotepath=%s", string(output), err, username, password, remotePath) + fmt.Sprintf("smbremotepath=%s", remotePath)); err != nil { + return fmt.Errorf("NewSmbGlobalMapping failed. output: %q, err: %v", string(output), err) } - return nil } func RemoveSmbGlobalMapping(remotePath string) error { - cmd := exec.Command("powershell", "/c", `Remove-SmbGlobalMapping -RemotePath $Env:smbremotepath -Force`) - cmd.Env = append(os.Environ(), fmt.Sprintf("smbremotepath=%s", remotePath)) - if output, err := cmd.CombinedOutput(); err != nil { + cmd := `Remove-SmbGlobalMapping -RemotePath $Env:smbremotepath -Force` + if output, err := util.RunPowershellCmd(cmd, fmt.Sprintf("smbremotepath=%s", remotePath)); err != nil { return fmt.Errorf("UnmountSmbShare failed. output: %q, err: %v", string(output), err) } return nil diff --git a/pkg/util/util.go b/pkg/util/util.go index 65e331f9b3..4dbe1e6f6d 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -16,6 +16,13 @@ limitations under the License. package util +import ( + "os" + "os/exec" + + "k8s.io/klog/v2" +) + const ( GiB = 1024 * 1024 * 1024 MaxPathLengthWindows = 260 @@ -55,3 +62,11 @@ func roundUpSize(volumeSizeBytes int64, allocationUnitBytes int64) int64 { } return roundedUp } + +func RunPowershellCmd(command string, envs ...string) ([]byte, error) { + cmd := exec.Command("powershell", "-Mta", "-NoProfile", "-Command", command) + cmd.Env = append(os.Environ(), envs...) + klog.V(8).Infof("Executing command: %q", cmd.String()) + out, err := cmd.CombinedOutput() + return out, err +} From a540843f154d791aaed4507326707d2778389089 Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Thu, 18 May 2023 16:33:56 +0000 Subject: [PATCH 099/109] fix: append nosharesock mount option on Linux node by default --- pkg/azurefile/azurefile.go | 8 +++++++- pkg/azurefile/azurefile_test.go | 31 +++++++++++++++++++++++++++---- pkg/azurefile/nodeserver.go | 2 +- pkg/azurefileplugin/main.go | 2 ++ 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/pkg/azurefile/azurefile.go b/pkg/azurefile/azurefile.go index 474b91a305..c7d0e08e79 100644 --- a/pkg/azurefile/azurefile.go +++ b/pkg/azurefile/azurefile.go @@ -201,6 +201,7 @@ type DriverOptions struct { KubeAPIBurst int EnableWindowsHostProcess bool AppendClosetimeoOption bool + AppendNoShareSockOption bool } // Driver implements all interfaces of CSI drivers @@ -223,6 +224,7 @@ type Driver struct { kubeAPIBurst int enableWindowsHostProcess bool appendClosetimeoOption bool + appendNoShareSockOption bool fileClient *azureFileClient mounter *mount.SafeFormatAndMount // lock per volume attach (only for vhd disk feature) @@ -271,6 +273,7 @@ func NewDriver(options *DriverOptions) *Driver { driver.kubeAPIBurst = options.KubeAPIBurst driver.enableWindowsHostProcess = options.EnableWindowsHostProcess driver.appendClosetimeoOption = options.AppendClosetimeoOption + driver.appendNoShareSockOption = options.AppendNoShareSockOption driver.volLockMap = newLockMap() driver.subnetLockMap = newLockMap() driver.volumeLocks = newVolumeLocks() @@ -429,7 +432,7 @@ func GetFileShareInfo(id string) (string, string, string, string, string, string } // check whether mountOptions contains file_mode, dir_mode, vers, if not, append default mode -func appendDefaultMountOptions(mountOptions []string, appendClosetimeoOption bool) []string { +func appendDefaultMountOptions(mountOptions []string, appendNoShareSockOption, appendClosetimeoOption bool) []string { var defaultMountOptions = map[string]string{ fileMode: defaultFileMode, dirMode: defaultDirMode, @@ -440,6 +443,9 @@ func appendDefaultMountOptions(mountOptions []string, appendClosetimeoOption boo if appendClosetimeoOption { defaultMountOptions["sloppy,closetimeo=0"] = "" } + if appendNoShareSockOption { + defaultMountOptions["nosharesock"] = "" + } // stores the mount options already included in mountOptions included := make(map[string]bool) diff --git a/pkg/azurefile/azurefile_test.go b/pkg/azurefile/azurefile_test.go index 0291afd676..1e71e9211b 100644 --- a/pkg/azurefile/azurefile_test.go +++ b/pkg/azurefile/azurefile_test.go @@ -92,9 +92,10 @@ func TestNewFakeDriver(t *testing.T) { func TestAppendDefaultMountOptions(t *testing.T) { tests := []struct { - options []string - appendClosetimeoOption bool - expected []string + options []string + appendClosetimeoOption bool + appendNoShareSockOption bool + expected []string }{ { options: []string{"dir_mode=0777"}, @@ -194,10 +195,32 @@ func TestAppendDefaultMountOptions(t *testing.T) { "sloppy,closetimeo=0", }, }, + { + options: []string{""}, + appendNoShareSockOption: true, + expected: []string{"", fmt.Sprintf("%s=%s", + fileMode, defaultFileMode), + fmt.Sprintf("%s=%s", dirMode, defaultDirMode), + fmt.Sprintf("%s=%s", actimeo, defaultActimeo), + mfsymlinks, + "nosharesock", + }, + }, + { + options: []string{"nosharesock"}, + appendNoShareSockOption: true, + expected: []string{fmt.Sprintf("%s=%s", + fileMode, defaultFileMode), + fmt.Sprintf("%s=%s", dirMode, defaultDirMode), + fmt.Sprintf("%s=%s", actimeo, defaultActimeo), + mfsymlinks, + "nosharesock", + }, + }, } for _, test := range tests { - result := appendDefaultMountOptions(test.options, test.appendClosetimeoOption) + result := appendDefaultMountOptions(test.options, test.appendNoShareSockOption, test.appendClosetimeoOption) sort.Strings(result) sort.Strings(test.expected) diff --git a/pkg/azurefile/nodeserver.go b/pkg/azurefile/nodeserver.go index cc1809bee4..5588be4b3d 100644 --- a/pkg/azurefile/nodeserver.go +++ b/pkg/azurefile/nodeserver.go @@ -294,7 +294,7 @@ func (d *Driver) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRe if ephemeralVol { cifsMountFlags = util.JoinMountOptions(cifsMountFlags, strings.Split(ephemeralVolMountOptions, ",")) } - mountOptions = appendDefaultMountOptions(cifsMountFlags, d.appendClosetimeoOption) + mountOptions = appendDefaultMountOptions(cifsMountFlags, d.appendNoShareSockOption, d.appendClosetimeoOption) } } diff --git a/pkg/azurefileplugin/main.go b/pkg/azurefileplugin/main.go index 963ee72a5e..d46c6fffec 100644 --- a/pkg/azurefileplugin/main.go +++ b/pkg/azurefileplugin/main.go @@ -58,6 +58,7 @@ var ( appendMountErrorHelpLink = flag.Bool("append-mount-error-help-link", true, "Whether to include a link for help with mount errors when a mount error occurs.") enableWindowsHostProcess = flag.Bool("enable-windows-host-process", false, "enable windows host process") appendClosetimeoOption = flag.Bool("append-closetimeo-option", false, "Whether appending closetimeo=0 option to smb mount command") + appendNoShareSockOption = flag.Bool("append-nosharesock-option", true, "Whether appending nosharesock option to smb mount command") ) func main() { @@ -101,6 +102,7 @@ func handle() { KubeAPIBurst: *kubeAPIBurst, EnableWindowsHostProcess: *enableWindowsHostProcess, AppendClosetimeoOption: *appendClosetimeoOption, + AppendNoShareSockOption: *appendNoShareSockOption, } driver := azurefile.NewDriver(&driverOptions) if driver == nil { From c5d275ff36f75a3ea6cca05e5cadfa352d9d069e Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Fri, 19 May 2023 11:23:05 +0000 Subject: [PATCH 100/109] cleanup: update new chart versions and remove deprecated versions --- README.md | 2 +- charts/index.yaml | 89 ++- .../v1.24.0/azurefile-csi-driver-v1.24.0.tgz | Bin 11415 -> 0 bytes .../v1.24.2/azurefile-csi-driver-v1.24.2.tgz | Bin 0 -> 11417 bytes .../azurefile-csi-driver/Chart.yaml | 4 +- .../azurefile-csi-driver/templates/NOTES.txt | 0 .../templates/_helpers.tpl | 0 .../templates/crd-csi-snapshot.yaml | 0 .../templates/csi-azurefile-controller.yaml | 0 .../templates/csi-azurefile-driver.yaml | 0 .../templates/csi-azurefile-node-windows.yaml | 0 .../templates/csi-azurefile-node.yaml | 0 .../templates/csi-snapshot-controller.yaml | 0 .../rbac-csi-azurefile-controller.yaml | 0 .../templates/rbac-csi-azurefile-node.yaml | 0 .../rbac-csi-snapshot-controller.yaml | 0 ...rviceaccount-csi-azurefile-controller.yaml | 0 .../serviceaccount-csi-azurefile-node.yaml | 0 ...erviceaccount-csi-snapshot-controller.yaml | 0 .../azurefile-csi-driver/values.yaml | 2 +- .../v1.26.0/azurefile-csi-driver-v1.26.0.tgz | Bin 11418 -> 0 bytes .../v1.26.0/azurefile-csi-driver/values.yaml | 254 ------- .../v1.26.1/azurefile-csi-driver-v1.26.1.tgz | Bin 11417 -> 0 bytes .../v1.26.1/azurefile-csi-driver/Chart.yaml | 5 - .../azurefile-csi-driver/templates/NOTES.txt | 5 - .../templates/_helpers.tpl | 49 -- .../templates/crd-csi-snapshot.yaml | 661 ------------------ .../templates/csi-azurefile-controller.yaml | 243 ------- .../templates/csi-azurefile-driver.yaml | 17 - .../templates/csi-azurefile-node-windows.yaml | 222 ------ .../templates/csi-azurefile-node.yaml | 217 ------ .../templates/csi-snapshot-controller.yaml | 65 -- .../rbac-csi-azurefile-controller.yaml | 207 ------ .../templates/rbac-csi-azurefile-node.yaml | 29 - .../rbac-csi-snapshot-controller.yaml | 80 --- ...rviceaccount-csi-azurefile-controller.yaml | 9 - .../serviceaccount-csi-azurefile-node.yaml | 9 - ...erviceaccount-csi-snapshot-controller.yaml | 9 - .../v1.26.2/azurefile-csi-driver-v1.26.2.tgz | Bin 11417 -> 0 bytes .../v1.26.2/azurefile-csi-driver/Chart.yaml | 5 - .../azurefile-csi-driver/templates/NOTES.txt | 5 - .../templates/_helpers.tpl | 49 -- .../templates/crd-csi-snapshot.yaml | 661 ------------------ .../templates/csi-azurefile-controller.yaml | 243 ------- .../templates/csi-azurefile-driver.yaml | 17 - .../templates/csi-azurefile-node-windows.yaml | 222 ------ .../templates/csi-azurefile-node.yaml | 217 ------ .../templates/csi-snapshot-controller.yaml | 65 -- .../rbac-csi-azurefile-controller.yaml | 207 ------ .../templates/rbac-csi-azurefile-node.yaml | 29 - .../rbac-csi-snapshot-controller.yaml | 80 --- ...rviceaccount-csi-azurefile-controller.yaml | 9 - .../serviceaccount-csi-azurefile-node.yaml | 9 - ...erviceaccount-csi-snapshot-controller.yaml | 9 - .../v1.26.2/azurefile-csi-driver/values.yaml | 254 ------- .../v1.26.3/azurefile-csi-driver-v1.26.3.tgz | Bin 0 -> 11420 bytes .../azurefile-csi-driver/Chart.yaml | 4 +- .../azurefile-csi-driver/templates/NOTES.txt | 0 .../templates/_helpers.tpl | 0 .../templates/crd-csi-snapshot.yaml | 0 .../templates/csi-azurefile-controller.yaml | 0 .../templates/csi-azurefile-driver.yaml | 0 .../templates/csi-azurefile-node-windows.yaml | 0 .../templates/csi-azurefile-node.yaml | 0 .../templates/csi-snapshot-controller.yaml | 0 .../rbac-csi-azurefile-controller.yaml | 0 .../templates/rbac-csi-azurefile-node.yaml | 0 .../rbac-csi-snapshot-controller.yaml | 0 ...rviceaccount-csi-azurefile-controller.yaml | 0 .../serviceaccount-csi-azurefile-node.yaml | 0 ...erviceaccount-csi-snapshot-controller.yaml | 0 .../azurefile-csi-driver/values.yaml | 2 +- .../crd-csi-snapshot.yaml | 0 .../csi-azurefile-controller.yaml | 10 +- .../csi-azurefile-driver.yaml | 2 +- .../csi-azurefile-node-windows.yaml | 6 +- .../csi-azurefile-node.yaml | 6 +- .../csi-snapshot-controller.yaml | 0 .../rbac-csi-azurefile-controller.yaml | 0 .../rbac-csi-azurefile-node.yaml | 0 .../rbac-csi-snapshot-controller.yaml | 0 .../v1.26.0/csi-azurefile-node-windows.yaml | 181 ----- deploy/v1.26.1/csi-azurefile-node.yaml | 157 ----- deploy/v1.26.2/crd-csi-snapshot.yaml | 659 ----------------- deploy/v1.26.2/csi-azurefile-controller.yaml | 184 ----- deploy/v1.26.2/csi-azurefile-driver.yaml | 15 - deploy/v1.26.2/csi-snapshot-controller.yaml | 46 -- .../rbac-csi-azurefile-controller.yaml | 194 ----- deploy/v1.26.2/rbac-csi-azurefile-node.yaml | 30 - .../v1.26.2/rbac-csi-snapshot-controller.yaml | 78 --- .../crd-csi-snapshot.yaml | 0 .../csi-azurefile-controller.yaml | 2 +- .../csi-azurefile-driver.yaml | 0 .../csi-azurefile-node-windows.yaml | 2 +- .../csi-azurefile-node.yaml | 2 +- .../csi-snapshot-controller.yaml | 0 .../rbac-csi-azurefile-controller.yaml | 0 .../rbac-csi-azurefile-node.yaml | 0 .../rbac-csi-snapshot-controller.yaml | 0 docs/install-azurefile-csi-driver.md | 2 +- ....26.2.md => install-csi-driver-v1.24.2.md} | 14 +- ....24.0.md => install-csi-driver-v1.26.3.md} | 14 +- 102 files changed, 77 insertions(+), 5792 deletions(-) delete mode 100644 charts/v1.24.0/azurefile-csi-driver-v1.24.0.tgz create mode 100644 charts/v1.24.2/azurefile-csi-driver-v1.24.2.tgz rename charts/{v1.26.0 => v1.24.2}/azurefile-csi-driver/Chart.yaml (75%) rename charts/{v1.24.0 => v1.24.2}/azurefile-csi-driver/templates/NOTES.txt (100%) rename charts/{v1.24.0 => v1.24.2}/azurefile-csi-driver/templates/_helpers.tpl (100%) rename charts/{v1.24.0 => v1.24.2}/azurefile-csi-driver/templates/crd-csi-snapshot.yaml (100%) rename charts/{v1.24.0 => v1.24.2}/azurefile-csi-driver/templates/csi-azurefile-controller.yaml (100%) rename charts/{v1.24.0 => v1.24.2}/azurefile-csi-driver/templates/csi-azurefile-driver.yaml (100%) rename charts/{v1.24.0 => v1.24.2}/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml (100%) rename charts/{v1.24.0 => v1.24.2}/azurefile-csi-driver/templates/csi-azurefile-node.yaml (100%) rename charts/{v1.24.0 => v1.24.2}/azurefile-csi-driver/templates/csi-snapshot-controller.yaml (100%) rename charts/{v1.24.0 => v1.24.2}/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml (100%) rename charts/{v1.24.0 => v1.24.2}/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml (100%) rename charts/{v1.24.0 => v1.24.2}/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml (100%) rename charts/{v1.24.0 => v1.24.2}/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml (100%) rename charts/{v1.24.0 => v1.24.2}/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml (100%) rename charts/{v1.24.0 => v1.24.2}/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml (100%) rename charts/{v1.24.0 => v1.24.2}/azurefile-csi-driver/values.yaml (99%) delete mode 100644 charts/v1.26.0/azurefile-csi-driver-v1.26.0.tgz delete mode 100644 charts/v1.26.0/azurefile-csi-driver/values.yaml delete mode 100644 charts/v1.26.1/azurefile-csi-driver-v1.26.1.tgz delete mode 100644 charts/v1.26.1/azurefile-csi-driver/Chart.yaml delete mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/NOTES.txt delete mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/_helpers.tpl delete mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/crd-csi-snapshot.yaml delete mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-controller.yaml delete mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-driver.yaml delete mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml delete mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node.yaml delete mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/csi-snapshot-controller.yaml delete mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml delete mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml delete mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml delete mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml delete mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml delete mode 100644 charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml delete mode 100644 charts/v1.26.2/azurefile-csi-driver-v1.26.2.tgz delete mode 100644 charts/v1.26.2/azurefile-csi-driver/Chart.yaml delete mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/NOTES.txt delete mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/_helpers.tpl delete mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/crd-csi-snapshot.yaml delete mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/csi-azurefile-controller.yaml delete mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/csi-azurefile-driver.yaml delete mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml delete mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/csi-azurefile-node.yaml delete mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/csi-snapshot-controller.yaml delete mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml delete mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml delete mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml delete mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml delete mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml delete mode 100644 charts/v1.26.2/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml delete mode 100644 charts/v1.26.2/azurefile-csi-driver/values.yaml create mode 100644 charts/v1.26.3/azurefile-csi-driver-v1.26.3.tgz rename charts/{v1.24.0 => v1.26.3}/azurefile-csi-driver/Chart.yaml (75%) rename charts/{v1.26.0 => v1.26.3}/azurefile-csi-driver/templates/NOTES.txt (100%) rename charts/{v1.26.0 => v1.26.3}/azurefile-csi-driver/templates/_helpers.tpl (100%) rename charts/{v1.26.0 => v1.26.3}/azurefile-csi-driver/templates/crd-csi-snapshot.yaml (100%) rename charts/{v1.26.0 => v1.26.3}/azurefile-csi-driver/templates/csi-azurefile-controller.yaml (100%) rename charts/{v1.26.0 => v1.26.3}/azurefile-csi-driver/templates/csi-azurefile-driver.yaml (100%) rename charts/{v1.26.0 => v1.26.3}/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml (100%) rename charts/{v1.26.0 => v1.26.3}/azurefile-csi-driver/templates/csi-azurefile-node.yaml (100%) rename charts/{v1.26.0 => v1.26.3}/azurefile-csi-driver/templates/csi-snapshot-controller.yaml (100%) rename charts/{v1.26.0 => v1.26.3}/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml (100%) rename charts/{v1.26.0 => v1.26.3}/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml (100%) rename charts/{v1.26.0 => v1.26.3}/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml (100%) rename charts/{v1.26.0 => v1.26.3}/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml (100%) rename charts/{v1.26.0 => v1.26.3}/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml (100%) rename charts/{v1.26.0 => v1.26.3}/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml (100%) rename charts/{v1.26.1 => v1.26.3}/azurefile-csi-driver/values.yaml (99%) rename deploy/{v1.26.0 => v1.24.2}/crd-csi-snapshot.yaml (100%) rename deploy/{v1.26.1 => v1.24.2}/csi-azurefile-controller.yaml (99%) rename deploy/{v1.26.0 => v1.24.2}/csi-azurefile-driver.yaml (92%) rename deploy/{v1.26.1 => v1.24.2}/csi-azurefile-node-windows.yaml (99%) rename deploy/{v1.26.2 => v1.24.2}/csi-azurefile-node.yaml (99%) rename deploy/{v1.26.0 => v1.24.2}/csi-snapshot-controller.yaml (100%) rename deploy/{v1.26.0 => v1.24.2}/rbac-csi-azurefile-controller.yaml (100%) rename deploy/{v1.26.0 => v1.24.2}/rbac-csi-azurefile-node.yaml (100%) rename deploy/{v1.26.0 => v1.24.2}/rbac-csi-snapshot-controller.yaml (100%) delete mode 100644 deploy/v1.26.0/csi-azurefile-node-windows.yaml delete mode 100644 deploy/v1.26.1/csi-azurefile-node.yaml delete mode 100644 deploy/v1.26.2/crd-csi-snapshot.yaml delete mode 100644 deploy/v1.26.2/csi-azurefile-controller.yaml delete mode 100644 deploy/v1.26.2/csi-azurefile-driver.yaml delete mode 100644 deploy/v1.26.2/csi-snapshot-controller.yaml delete mode 100644 deploy/v1.26.2/rbac-csi-azurefile-controller.yaml delete mode 100644 deploy/v1.26.2/rbac-csi-azurefile-node.yaml delete mode 100644 deploy/v1.26.2/rbac-csi-snapshot-controller.yaml rename deploy/{v1.26.1 => v1.26.3}/crd-csi-snapshot.yaml (100%) rename deploy/{v1.26.0 => v1.26.3}/csi-azurefile-controller.yaml (99%) rename deploy/{v1.26.1 => v1.26.3}/csi-azurefile-driver.yaml (100%) rename deploy/{v1.26.2 => v1.26.3}/csi-azurefile-node-windows.yaml (99%) rename deploy/{v1.26.0 => v1.26.3}/csi-azurefile-node.yaml (99%) rename deploy/{v1.26.1 => v1.26.3}/csi-snapshot-controller.yaml (100%) rename deploy/{v1.26.1 => v1.26.3}/rbac-csi-azurefile-controller.yaml (100%) rename deploy/{v1.26.1 => v1.26.3}/rbac-csi-azurefile-node.yaml (100%) rename deploy/{v1.26.1 => v1.26.3}/rbac-csi-snapshot-controller.yaml (100%) rename docs/{install-csi-driver-v1.26.2.md => install-csi-driver-v1.24.2.md} (81%) rename docs/{install-csi-driver-v1.24.0.md => install-csi-driver-v1.26.3.md} (81%) diff --git a/README.md b/README.md index 6221a03471..c95845149e 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Disclaimer: Deploying this driver manually is not an officially supported Micros |----------------|---------------------------------------------------------- |-----------------------| |master branch |mcr.microsoft.com/k8s/csi/azurefile-csi:latest | 1.21+ | |v1.27.0 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.27.0 | 1.21+ | -|v1.26.2 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.2 | 1.21+ | +|v1.26.3 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.26.3 | 1.21+ | |v1.25.1 |mcr.microsoft.com/oss/kubernetes-csi/azurefile-csi:v1.25.1 | 1.21+ | ### Driver parameters diff --git a/charts/index.yaml b/charts/index.yaml index 596d73c20c..5c297956a0 100644 --- a/charts/index.yaml +++ b/charts/index.yaml @@ -3,7 +3,7 @@ entries: azurefile-csi-driver: - apiVersion: v1 appVersion: v1.27.0 - created: "2023-04-27T03:26:15.812799626Z" + created: "2023-05-19T11:21:33.715062026Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 760a05a835ba3f21949988daadbfb9b03b5e9e3a19f46372a53a0f01beba9f0e name: azurefile-csi-driver @@ -11,26 +11,17 @@ entries: - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/v1.27.0/azurefile-csi-driver-v1.27.0.tgz version: v1.27.0 - apiVersion: v1 - appVersion: v1.26.1 - created: "2023-04-27T03:26:15.811798883Z" + appVersion: v1.26.3 + created: "2023-05-19T11:21:33.71402389Z" description: Azure File Container Storage Interface (CSI) Storage Plugin - digest: b1c78e2c38869f9430f3e2e671fb168db803eab2fbc0ef905eacdf8794d7968a + digest: 61be13c10618eb0dac60bd27b26a037b5c251fffc945345d03b207a3e091ba76 name: azurefile-csi-driver urls: - - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/v1.26.1/azurefile-csi-driver-v1.26.1.tgz - version: v1.26.1 - - apiVersion: v1 - appVersion: v1.26.0 - created: "2023-04-27T03:26:15.810805921Z" - description: Azure File Container Storage Interface (CSI) Storage Plugin - digest: 98d15a8ced671a7c3d9aec8ebe00b58abeecb5f65ab966c9c01c4f39121adc0c - name: azurefile-csi-driver - urls: - - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/v1.26.0/azurefile-csi-driver-v1.26.0.tgz - version: v1.26.0 + - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/v1.26.3/azurefile-csi-driver-v1.26.3.tgz + version: v1.26.3 - apiVersion: v1 appVersion: v1.25.1 - created: "2023-04-27T03:26:15.809805219Z" + created: "2023-05-19T11:21:33.712971785Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 2bf374cc321c5bc8e76e06cd5df85ce7d7d14574397e7e7f7173077393f554c4 name: azurefile-csi-driver @@ -39,7 +30,7 @@ entries: version: v1.25.1 - apiVersion: v1 appVersion: v1.25.0 - created: "2023-04-27T03:26:15.808794406Z" + created: "2023-05-19T11:21:33.711199479Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: ba80dcd23dade4e62b39d3dc638c599e9d5e100009fa14d4164bfc8966fea3dd name: azurefile-csi-driver @@ -47,17 +38,17 @@ entries: - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/v1.25.0/azurefile-csi-driver-v1.25.0.tgz version: v1.25.0 - apiVersion: v1 - appVersion: v1.24.0 - created: "2023-04-27T03:26:15.806976438Z" + appVersion: v1.24.2 + created: "2023-05-19T11:21:33.710206298Z" description: Azure File Container Storage Interface (CSI) Storage Plugin - digest: 1905eb862745d4a7f57c5de96848cee194adf827086984b75bcaefce5c90142b + digest: 6829b8ac92a667028e5b7a4f69272bf344a7fd5578b079174639037b70485b4e name: azurefile-csi-driver urls: - - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/v1.24.0/azurefile-csi-driver-v1.24.0.tgz - version: v1.24.0 + - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/v1.24.2/azurefile-csi-driver-v1.24.2.tgz + version: v1.24.2 - apiVersion: v1 appVersion: v1.23.0 - created: "2023-04-27T03:26:15.805997746Z" + created: "2023-05-19T11:21:33.709204395Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 5fcb33617d16e90df1e7041b0df02e5bd92595e86381db30d356b0b2e3500bc4 name: azurefile-csi-driver @@ -66,7 +57,7 @@ entries: version: v1.23.0 - apiVersion: v1 appVersion: v1.22.0 - created: "2023-04-27T03:26:15.804972003Z" + created: "2023-05-19T11:21:33.708214774Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 253d87a8b876dbdd55870a7fee88547393179d03f193661125f5a0b63411f922 name: azurefile-csi-driver @@ -75,7 +66,7 @@ entries: version: v1.22.0 - apiVersion: v1 appVersion: v1.21.0 - created: "2023-04-27T03:26:15.803988889Z" + created: "2023-05-19T11:21:33.707178525Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: d45bf3455ebadc9cc5afaf9da66aa1ea1d4b719cfdff5af661f93bb26c01a504 name: azurefile-csi-driver @@ -84,7 +75,7 @@ entries: version: v1.21.0 - apiVersion: v1 appVersion: v1.20.0 - created: "2023-04-27T03:26:15.802914632Z" + created: "2023-05-19T11:21:33.706223662Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 7cc43d57a79137aea5414fb51a9bbd77bb679b29ee49c06865c1a5b9ba60be99 name: azurefile-csi-driver @@ -93,7 +84,7 @@ entries: version: v1.20.0 - apiVersion: v1 appVersion: v1.19.0 - created: "2023-04-27T03:26:15.800484833Z" + created: "2023-05-19T11:21:33.704067009Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 18f6efbed424efd661fde43be2e5a48a5012a46a7938c33b36963cbd9875a5af name: azurefile-csi-driver @@ -102,7 +93,7 @@ entries: version: v1.19.0 - apiVersion: v1 appVersion: v1.18.0 - created: "2023-04-27T03:26:15.799588392Z" + created: "2023-05-19T11:21:33.703134164Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 696ca23d9ee517f71ef5e852955c8d0f1017c331c025426c6fcbe7a06d006c66 name: azurefile-csi-driver @@ -111,7 +102,7 @@ entries: version: v1.18.0 - apiVersion: v1 appVersion: v1.17.0 - created: "2023-04-27T03:26:15.798695474Z" + created: "2023-05-19T11:21:33.702220551Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 5632f61265a3b78dce3e2b15e07cc9b14a7f54a778878c02ca2d9fe69ca0344e name: azurefile-csi-driver @@ -120,7 +111,7 @@ entries: version: v1.17.0 - apiVersion: v1 appVersion: v1.16.0 - created: "2023-04-27T03:26:15.797799838Z" + created: "2023-05-19T11:21:33.701278583Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: a7a2d57e8eca7dc06c8b2cffb9bccb857753eb110b8e70760b3e04f4e6a87552 name: azurefile-csi-driver @@ -129,7 +120,7 @@ entries: version: v1.16.0 - apiVersion: v1 appVersion: v1.15.0 - created: "2023-04-27T03:26:15.79686677Z" + created: "2023-05-19T11:21:33.700353256Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: c1a31dadce233a90c19dce70f6cc92ba2e20bbaa1b1883baea72381d09303118 name: azurefile-csi-driver @@ -138,7 +129,7 @@ entries: version: v1.15.0 - apiVersion: v1 appVersion: v1.14.0 - created: "2023-04-27T03:26:15.795285167Z" + created: "2023-05-19T11:21:33.69940207Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 0c9ad4afa5ebfdb2851ad93eb16a0382d61448714b7556899360730a2fdf463a name: azurefile-csi-driver @@ -147,7 +138,7 @@ entries: version: v1.14.0 - apiVersion: v1 appVersion: v1.13.0 - created: "2023-04-27T03:26:15.794207336Z" + created: "2023-05-19T11:21:33.697501581Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 214042b029d858b50a0f8bba33a7aa2b41d1b67bce16f957ca183ae7438dac3f name: azurefile-csi-driver @@ -156,7 +147,7 @@ entries: version: v1.13.0 - apiVersion: v1 appVersion: v1.12.0 - created: "2023-04-27T03:26:15.793250487Z" + created: "2023-05-19T11:21:33.69657813Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: fbd63929671066a26df898d32282a6e79c39499a39c71761c546d069459d847d name: azurefile-csi-driver @@ -165,7 +156,7 @@ entries: version: v1.12.0 - apiVersion: v1 appVersion: v1.11.0 - created: "2023-04-27T03:26:15.792329033Z" + created: "2023-05-19T11:21:33.69566567Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 76bd438f8391d08235b09fbca859f25a9fcf8e018fd1e7e33444ca9ea946ce4b name: azurefile-csi-driver @@ -174,7 +165,7 @@ entries: version: v1.11.0 - apiVersion: v1 appVersion: v1.10.0 - created: "2023-04-27T03:26:15.791388709Z" + created: "2023-05-19T11:21:33.69474349Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 845a9de8b571b255d05ae9c643d9b90a57fe6507ff3fb735c88b41f99f6f28dc name: azurefile-csi-driver @@ -183,7 +174,7 @@ entries: version: v1.10.0 - apiVersion: v1 appVersion: v1.9.0 - created: "2023-04-27T03:26:15.819767514Z" + created: "2023-05-19T11:21:33.721211127Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 59a8057fbbd6d59919b84ef0c3396d5a0a46d1f29df604457db676f4af63c714 name: azurefile-csi-driver @@ -192,7 +183,7 @@ entries: version: v1.9.0 - apiVersion: v1 appVersion: v1.8.0 - created: "2023-04-27T03:26:15.818039169Z" + created: "2023-05-19T11:21:33.720213433Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 455b7c342194311046df526d10926d94f3bef24f753a07003fb1cad211c4cb52 name: azurefile-csi-driver @@ -201,7 +192,7 @@ entries: version: v1.8.0 - apiVersion: v1 appVersion: v1.7.0 - created: "2023-04-27T03:26:15.817041748Z" + created: "2023-05-19T11:21:33.719195592Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 057b3f6ef6001d3457fbffc27f90316c981a089696abd3d38bcc8de5537dfa6f name: azurefile-csi-driver @@ -210,7 +201,7 @@ entries: version: v1.7.0 - apiVersion: v1 appVersion: v1.6.0 - created: "2023-04-27T03:26:15.816303025Z" + created: "2023-05-19T11:21:33.717623514Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: cc2a0dda824cdda4e8141e26878bbb481c5a52e45785a5dbf72e54f2a376e522 name: azurefile-csi-driver @@ -219,7 +210,7 @@ entries: version: v1.6.0 - apiVersion: v1 appVersion: v1.5.0 - created: "2023-04-27T03:26:15.815588905Z" + created: "2023-05-19T11:21:33.716960336Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 2258177477415ddecd83dc46dfd88833223623224c7fe396590b617082bcd845 name: azurefile-csi-driver @@ -228,7 +219,7 @@ entries: version: v1.5.0 - apiVersion: v1 appVersion: v1.4.0 - created: "2023-04-27T03:26:15.814869863Z" + created: "2023-05-19T11:21:33.71625238Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 40e9bc4ee187789166fcb7c3c82b85b33ecd3a6096266fe74e411d6b48961ece name: azurefile-csi-driver @@ -237,7 +228,7 @@ entries: version: v1.4.0 - apiVersion: v1 appVersion: v1.3.0 - created: "2023-04-27T03:26:15.814109055Z" + created: "2023-05-19T11:21:33.715597503Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 12942f422b7cccbfe950bbdbd5c844f5ae4b7c292f32389cba312730a6fe9a62 name: azurefile-csi-driver @@ -246,7 +237,7 @@ entries: version: v1.3.0 - apiVersion: v1 appVersion: v1.2.0 - created: "2023-04-27T03:26:15.800988509Z" + created: "2023-05-19T11:21:33.70457987Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: b62f44b757416a9e1f5a91e19285f5f5056ec6068802dd9cd82373bef40c9ee9 name: azurefile-csi-driver @@ -255,7 +246,7 @@ entries: version: v1.2.0 - apiVersion: v1 appVersion: v1.1.0 - created: "2023-04-27T03:26:15.790424697Z" + created: "2023-05-19T11:21:33.693803438Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 675d96b309a1c5c491053ebbb854c046737420929c4f0692839afdaaf0db3933 name: azurefile-csi-driver @@ -264,7 +255,7 @@ entries: version: v1.1.0 - apiVersion: v1 appVersion: v1.0.0 - created: "2023-04-27T03:26:15.78990135Z" + created: "2023-05-19T11:21:33.693273519Z" description: Azure File Container Storage Interface (CSI) Storage Plugin digest: 6fd5e54e949ef1061a08d5477bc580204c91dde8f01da195e95dd60ade209492 name: azurefile-csi-driver @@ -273,11 +264,11 @@ entries: version: v1.0.0 - apiVersion: v1 appVersion: latest - created: "2023-04-27T03:26:15.788959329Z" + created: "2023-05-19T11:21:33.692751585Z" description: Azure File Container Storage Interface (CSI) Storage Plugin - digest: f1bdd4051c351a3bddd4fe6031f5517b5af9340a443e9e65f1baeaf6275dab09 + digest: bb330d0eb633f6079553b8ef1c164eed99a8db7640663d2c4766a9d9d02e2ac9 name: azurefile-csi-driver urls: - https://raw.githubusercontent.com/kubernetes-sigs/azurefile-csi-driver/master/charts/latest/azurefile-csi-driver-v0.0.0.tgz version: v0.0.0 -generated: "2023-04-27T03:26:15.787337581Z" +generated: "2023-05-19T11:21:33.690634436Z" diff --git a/charts/v1.24.0/azurefile-csi-driver-v1.24.0.tgz b/charts/v1.24.0/azurefile-csi-driver-v1.24.0.tgz deleted file mode 100644 index e035e003540ba6327f66823a57d65c74112c7850..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11415 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 NJvqe45Y>^??Tx*$Z9C_jyYH>wC)m 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 O2I0&vRD;!kgZ&Rb{gqAt literal 0 HcmV?d00001 diff --git a/charts/v1.26.0/azurefile-csi-driver/Chart.yaml b/charts/v1.24.2/azurefile-csi-driver/Chart.yaml similarity index 75% rename from charts/v1.26.0/azurefile-csi-driver/Chart.yaml rename to charts/v1.24.2/azurefile-csi-driver/Chart.yaml index c30547c2df..dd02b74f3c 100644 --- a/charts/v1.26.0/azurefile-csi-driver/Chart.yaml +++ b/charts/v1.24.2/azurefile-csi-driver/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: v1.26.0 +appVersion: v1.24.2 description: Azure File Container Storage Interface (CSI) Storage Plugin name: azurefile-csi-driver -version: v1.26.0 +version: v1.24.2 diff --git a/charts/v1.24.0/azurefile-csi-driver/templates/NOTES.txt b/charts/v1.24.2/azurefile-csi-driver/templates/NOTES.txt similarity index 100% rename from charts/v1.24.0/azurefile-csi-driver/templates/NOTES.txt rename to charts/v1.24.2/azurefile-csi-driver/templates/NOTES.txt diff --git a/charts/v1.24.0/azurefile-csi-driver/templates/_helpers.tpl b/charts/v1.24.2/azurefile-csi-driver/templates/_helpers.tpl similarity index 100% rename from charts/v1.24.0/azurefile-csi-driver/templates/_helpers.tpl rename to charts/v1.24.2/azurefile-csi-driver/templates/_helpers.tpl diff --git a/charts/v1.24.0/azurefile-csi-driver/templates/crd-csi-snapshot.yaml b/charts/v1.24.2/azurefile-csi-driver/templates/crd-csi-snapshot.yaml similarity index 100% rename from charts/v1.24.0/azurefile-csi-driver/templates/crd-csi-snapshot.yaml rename to charts/v1.24.2/azurefile-csi-driver/templates/crd-csi-snapshot.yaml diff --git a/charts/v1.24.0/azurefile-csi-driver/templates/csi-azurefile-controller.yaml b/charts/v1.24.2/azurefile-csi-driver/templates/csi-azurefile-controller.yaml similarity index 100% rename from charts/v1.24.0/azurefile-csi-driver/templates/csi-azurefile-controller.yaml rename to charts/v1.24.2/azurefile-csi-driver/templates/csi-azurefile-controller.yaml diff --git a/charts/v1.24.0/azurefile-csi-driver/templates/csi-azurefile-driver.yaml b/charts/v1.24.2/azurefile-csi-driver/templates/csi-azurefile-driver.yaml similarity index 100% rename from charts/v1.24.0/azurefile-csi-driver/templates/csi-azurefile-driver.yaml rename to charts/v1.24.2/azurefile-csi-driver/templates/csi-azurefile-driver.yaml diff --git a/charts/v1.24.0/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml b/charts/v1.24.2/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml similarity index 100% rename from charts/v1.24.0/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml rename to charts/v1.24.2/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml diff --git a/charts/v1.24.0/azurefile-csi-driver/templates/csi-azurefile-node.yaml b/charts/v1.24.2/azurefile-csi-driver/templates/csi-azurefile-node.yaml similarity index 100% rename from charts/v1.24.0/azurefile-csi-driver/templates/csi-azurefile-node.yaml rename to charts/v1.24.2/azurefile-csi-driver/templates/csi-azurefile-node.yaml diff --git a/charts/v1.24.0/azurefile-csi-driver/templates/csi-snapshot-controller.yaml b/charts/v1.24.2/azurefile-csi-driver/templates/csi-snapshot-controller.yaml similarity index 100% rename from charts/v1.24.0/azurefile-csi-driver/templates/csi-snapshot-controller.yaml rename to charts/v1.24.2/azurefile-csi-driver/templates/csi-snapshot-controller.yaml diff --git a/charts/v1.24.0/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml b/charts/v1.24.2/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml similarity index 100% rename from charts/v1.24.0/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml rename to charts/v1.24.2/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml diff --git a/charts/v1.24.0/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml b/charts/v1.24.2/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml similarity index 100% rename from charts/v1.24.0/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml rename to charts/v1.24.2/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml diff --git a/charts/v1.24.0/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml b/charts/v1.24.2/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml similarity index 100% rename from charts/v1.24.0/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml rename to charts/v1.24.2/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml diff --git a/charts/v1.24.0/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml b/charts/v1.24.2/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml similarity index 100% rename from charts/v1.24.0/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml rename to charts/v1.24.2/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml diff --git a/charts/v1.24.0/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml b/charts/v1.24.2/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml similarity index 100% rename from charts/v1.24.0/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml rename to charts/v1.24.2/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml diff --git a/charts/v1.24.0/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml b/charts/v1.24.2/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml similarity index 100% rename from charts/v1.24.0/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml rename to charts/v1.24.2/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml diff --git a/charts/v1.24.0/azurefile-csi-driver/values.yaml b/charts/v1.24.2/azurefile-csi-driver/values.yaml similarity index 99% rename from charts/v1.24.0/azurefile-csi-driver/values.yaml rename to charts/v1.24.2/azurefile-csi-driver/values.yaml index 6d9201762a..7fb6f0e4dc 100644 --- a/charts/v1.24.0/azurefile-csi-driver/values.yaml +++ b/charts/v1.24.2/azurefile-csi-driver/values.yaml @@ -2,7 +2,7 @@ image: baseRepo: mcr.microsoft.com azurefile: repository: /oss/kubernetes-csi/azurefile-csi - tag: v1.24.0 + tag: v1.24.2 pullPolicy: IfNotPresent csiProvisioner: repository: /oss/kubernetes-csi/csi-provisioner diff --git a/charts/v1.26.0/azurefile-csi-driver-v1.26.0.tgz b/charts/v1.26.0/azurefile-csi-driver-v1.26.0.tgz deleted file mode 100644 index 086cc0f25fad1441b61b5f5a4e62620d15bafc76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11418 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 XUo3-fA)o$@Aw!-`9;BfvprQT;{O+Gd diff --git a/charts/v1.26.0/azurefile-csi-driver/values.yaml b/charts/v1.26.0/azurefile-csi-driver/values.yaml deleted file mode 100644 index 043a5ad872..0000000000 --- a/charts/v1.26.0/azurefile-csi-driver/values.yaml +++ /dev/null @@ -1,254 +0,0 @@ -image: - baseRepo: mcr.microsoft.com - azurefile: - repository: /oss/kubernetes-csi/azurefile-csi - tag: v1.26.0 - pullPolicy: IfNotPresent - csiProvisioner: - repository: /oss/kubernetes-csi/csi-provisioner - tag: v3.3.0 - pullPolicy: IfNotPresent - csiAttacher: - repository: /oss/kubernetes-csi/csi-attacher - tag: v4.0.0 - pullPolicy: IfNotPresent - csiResizer: - repository: /oss/kubernetes-csi/csi-resizer - tag: v1.6.0 - pullPolicy: IfNotPresent - livenessProbe: - repository: /oss/kubernetes-csi/livenessprobe - tag: v2.8.0 - pullPolicy: IfNotPresent - nodeDriverRegistrar: - repository: /oss/kubernetes-csi/csi-node-driver-registrar - tag: v2.6.2 - pullPolicy: IfNotPresent - -## Reference to one or more secrets to be used when pulling images -## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ -imagePullSecrets: [] -# - name: myRegistryKeySecretName - -# -- Custom labels to add into metadata -customLabels: {} - # k8s-app: azurefile-csi-driver - -serviceAccount: - create: true # When true, service accounts will be created for you. Set to false if you want to use your own. - controller: csi-azurefile-controller-sa # Name of Service Account to be created or used - node: csi-azurefile-node-sa # Name of Service Account to be created or used - snapshotController: csi-snapshot-controller-sa # Name of Service Account to be created or used - -rbac: - create: true - name: azurefile - -controller: - name: csi-azurefile-controller - cloudConfigSecretName: azure-cloud-provider - cloudConfigSecretNamespace: kube-system - allowEmptyCloudConfig: true - replicas: 2 - hostNetwork: true # this setting could be disabled if controller does not depend on MSI setting - metricsPort: 29614 - livenessProbe: - healthPort: 29612 - runOnMaster: false - runOnControlPlane: false - attachRequired: false - logLevel: 5 - labels: {} - annotations: {} - podLabels: {} - podAnnotations: {} - resources: - csiProvisioner: - limits: - cpu: 1 - memory: 500Mi - requests: - cpu: 10m - memory: 20Mi - csiAttacher: - limits: - cpu: 1 - memory: 500Mi - requests: - cpu: 10m - memory: 20Mi - csiResizer: - limits: - cpu: 1 - memory: 500Mi - requests: - cpu: 10m - memory: 20Mi - csiSnapshotter: - limits: - cpu: 1 - memory: 100Mi - requests: - cpu: 10m - memory: 20Mi - livenessProbe: - limits: - cpu: 1 - memory: 100Mi - requests: - cpu: 10m - memory: 20Mi - azurefile: - limits: - cpu: 1 - memory: 200Mi - requests: - cpu: 10m - memory: 20Mi - kubeconfig: "" - affinity: {} - nodeSelector: {} - tolerations: - - key: "node-role.kubernetes.io/master" - operator: "Exists" - effect: "NoSchedule" - - key: "node-role.kubernetes.io/controlplane" - operator: "Exists" - effect: "NoSchedule" - - key: "node-role.kubernetes.io/control-plane" - operator: "Exists" - effect: "NoSchedule" - -node: - cloudConfigSecretName: azure-cloud-provider - cloudConfigSecretNamespace: kube-system - allowEmptyCloudConfig: true - allowInlineVolumeKeyAccessWithIdentity: false - metricsPort: 29615 - livenessProbe: - healthPort: 29613 - logLevel: 5 - -snapshot: - enabled: false - image: - csiSnapshotter: - repository: /oss/kubernetes-csi/csi-snapshotter - tag: v5.0.1 - pullPolicy: IfNotPresent - csiSnapshotController: - repository: /oss/kubernetes-csi/snapshot-controller - tag: v5.0.1 - pullPolicy: IfNotPresent - snapshotController: - name: csi-snapshot-controller - replicas: 2 - labels: {} - annotations: {} - podLabels: {} - podAnnotations: {} - resources: - limits: - cpu: 1 - memory: 100Mi - requests: - cpu: 10m - memory: 20Mi - -feature: - enableGetVolumeStats: true - -driver: - name: file.csi.azure.com - customUserAgent: "" - userAgentSuffix: "OSS-helm" - azureGoSDKLogLevel: "" # available values: ""(no logs), DEBUG, INFO, WARNING, ERROR - httpsProxy: "" - httpProxy: "" - -linux: - enabled: true - dsName: csi-azurefile-node # daemonset name - dnsPolicy: Default # available values: Default, ClusterFirst, ClusterFirstWithHostNet, None - kubelet: /var/lib/kubelet - kubeconfig: "" - distro: debian # available values: debian, fedora - mountPermissions: 0777 - labels: {} - annotations: {} - podLabels: {} - podAnnotations: {} - resources: - livenessProbe: - limits: - memory: 100Mi - requests: - cpu: 10m - memory: 20Mi - nodeDriverRegistrar: - limits: - memory: 100Mi - requests: - cpu: 10m - memory: 20Mi - azurefile: - limits: - memory: 400Mi - requests: - cpu: 10m - memory: 20Mi - tolerations: - - operator: "Exists" - nodeSelector: {} - affinity: {} - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: type - operator: NotIn - values: - - virtual-kubelet - -windows: - enabled: true - dsName: csi-azurefile-node-win # daemonset name - kubelet: 'C:\var\lib\kubelet' - kubeconfig: "" - labels: {} - annotations: {} - podLabels: {} - podAnnotations: {} - resources: - livenessProbe: - limits: - memory: 150Mi - requests: - cpu: 10m - memory: 40Mi - nodeDriverRegistrar: - limits: - memory: 150Mi - requests: - cpu: 30m - memory: 40Mi - azurefile: - limits: - memory: 200Mi - requests: - cpu: 10m - memory: 40Mi - tolerations: - - key: "node.kubernetes.io/os" - operator: "Exists" - effect: "NoSchedule" - nodeSelector: {} - affinity: {} - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: type - operator: NotIn - values: - - virtual-kubelet diff --git a/charts/v1.26.1/azurefile-csi-driver-v1.26.1.tgz b/charts/v1.26.1/azurefile-csi-driver-v1.26.1.tgz deleted file mode 100644 index 0b2623bf217c4eb906e5dc2450a33adc8b8608d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11417 zcmZ8{Q*b3v)9oY^XJSok+cqb*&53P0C$??dwryjQOl+R${PW+sUww7&e(0*by8Eqb zRadV?7zKm=?SCJL`Wvm0lrocvlpKewCpWt>t2&dZ3cIDY3O9#>x;lrPhK-exovEj) zl0CnanT_qYOJ7fCT+UYeufJtN3#?}Ev6+RKQ>;G6oh1nvak==v$R{SUuugy?JKs@%+NWaL;@P&|m>T z_o0?|8pLZ{PX{SK2nLuUQnsy&1E%Q@?sY+&%O^f$2FikEK>}Jo;XO3MdDtRUG&npx znbA9ldF+(_v31DD%cHkT&-?chLOGZ#CA@wZHAh{0^~=YGljFI2)k)Bgca(@2>Hu@# z9xvA>FV!R{>OhzhwB;ccK*@AY>=Fg3D?Bbi8deHlT! zNtCB>qy2%M0c4`l;Kq26(ce+`o#I74ec-83_Y1nH6?bq7(2C83%PF{`C4bYHQAu=R zOGAfTc}-(uKtsp_<0fd->-QUr_df}};; zC@phBtPl$nbm=6deqANQdLrJ(-YLKuOi-gp1td#<=wbqMGcn>|d@h2^(kbwv?tj9F zWrz`k2=Nb7y&b&K)$WQ)LvcBdkRLjQJcAsY-8E~#$^v}3<)Wz1J;WGKku;@R3Ny_P z39pn5-qJr|ALi?~e8!WLlkT-@Elw)nkJhf*Z+6*78ke-h<9ugTgS zPX9=>PwidZB2?Oh&x3ImXXmlm(TD9le=k=lPw_PYsPxU=$nUa~Xjnl^evU6+nbD_O zN9OHQocGgDaek_2UAyX!P)p4(?_X|Wu8n)6DHxXQI#ccSj8H?ubSwyVF0~g)*){f} z!l9gva2Ob~v9-yaxUTre^!@{g>RN-1^wkYvmxzbq?Gq9Ks6m;lzfj0n17G(kdv<>()OH z$J0_mw%mD7hvSlizH%LuUS-Zg{jmj|pmSK^R*heYB!9by0c#cP+^-nbR)8udXCAQS(fL^SC20W$6C(FXTX!y9yI`L{D*@nAT{47Ko7 zI>6G&aZi|zy{6T#>6|(2@@SGbrQZH6@IpLj?@MA|zdw zqpkuT6AtG+K(FTy7HsX{dUo-bGz)2rk?2e5hcLALb#L3rbSokTz5lAVsROU&6LIq( z??H}melWT}Oxxd-Zoz?jf^-w0siNQ_`LDJ+pRewBgWnQCD9Qxc#t>!)`jA%I+tktX z{#Sm$#fvlJvKQh~f<%@1S^{H}PkW7`P?wImJp7}9bVZ@hkS3@~2SV;M?;c3JpUDZS zYXfmmj``C1(*e$Zz~1ya@|VRWq2Kbzn0QT=-4{m#yx#UQ`*#5X?933@s2Dw%IzjbJ z7Jh9H$u@`Hh+YWG7fzOO#FVPBN}#$yVAbh~q|uix7~82kK9tg16{t<%-2bwUg#;5K zx=`~NAR&FIJgUPX_lJq@)slkc4#*l=(%r54T~#Ydk(k+4?y7LGhH|(4B_{bDJ5mi+ zL{IP@2Up16dpJKP2YHMcSf)0hZ)3CLt)HUCA79`v5*ui!nou zY5*E}*}8*Z=f@pH3^)AzPI9|Slsh1+X9%3%gik_|KW?iQ#{}lOznNR{otcD8(Hq?L zj|pma*19#%wYA>s{aDg=edrMstqT8n2-{`W$T$2x9X3t9$oXG^)Cxbx($HgA{E!1k(esn8V9+T;gkYzGMg(MQe#S`_NHQ<0Jt`{B5ooydZo-Iyg z>+DnLuju;9`O&gi-@S;V@1ds_)`JURlEl83>g4$pbZX_LWYH+NJ=@A8&RtB*utu8# z*3o4~#ghjM)Hwi~S&d+wY(^B7y5`&?%4f7J>Q<86OE%RqG_6Cm|9Ech5E6qTxkP`5 zg`3{3;yH2UQ93LjG9tJloI5`rW$09sr2iV7nHy3-2-NHgy8U{Ss6Z3N^{_ISXb+V5 z1IQsHx#YUwK1&r}t}3qdt4T!#41Zu(S8K!ZbA&5OCVsm=m;Iw4WWo_u4!xac4co>k z{DY;~k4vj4i}b7bV^Hzh2sZUv*14gMnM&(Uw`wdYbF>=3NdgnWBTqpY*jDZ9M3|( zv##Zt$7&&JO~)}LZc&-1Gn7deQbg<8S@&7aMW{w}TOo*G3bw?0MwL|6=rp-N zqOJLj1zL6<)K_J!k3FMh@BKVGGh5Ev;vN+*lBDv=stiJq@AR}B)$*F4(v7Yng68X} zyLIkUH-GD+E7$5WEy-lpiGaj8w;Z96aE73kxubc{sg&;YH6ynN12UyXpc(*vG=RZ3 zB{78!W*Z#8%XUzpN_WRDgiHsFQXY4nQRjlekr*V-D{L_jA7y=KUgTW+!$N#JUGdg$ zvkKoyg5pccImvgtxlOIg^nRqeQB@PCr2JPI*Em7U{jR(Ld769^?}!OpV#xHQ#7dl{ zr(F3&( zUeb&997+gwan$j5$T53Zj}T#9#A zceuf)sNF}Ss$FVrTq9uK{s}?WltJ!b7QOGPfv8sf-$n(31 z!)G`9Pe8lnQ@it#F&HoQOxo!q^WBr)Y;kzAombnEHl)yJ`#@aev|r1QJ8ZP!joHozy9ERpIjo^ zW~sX@?-+2&eF#t5>QlKDCC^PPpi+&ELt?#UohHdm0Q=#FjQB)OI^;XCby8Uf&2T4l z*Na#;K|RfyK=JE0M1+z{IN&d$NfYZsW?znP6y)i}sCMJu0)1#!F+?l18NbTdCSO8d za2Sm5j`SMZWGS2lS%$TZeI&Ux-63RM=P$%EY;|VFD*SVkwMZVJJ?`H`$l7*sus$p3 zGvSpyiJ0$_OzEEWV70AKJTt+T2|;4*QP0jrMy#*CL1S)72%}Kbcj~%CDMh@Tks1= zwJ|2emztp|JBXuhJobwAk90djCTbV@4p1I1WZ?|GwX3Aa(Z!f^H%x^lp^vp@r4ebS zs#nHqA$w&qssE8)b`Q>HHk1Ae?4_HB(!%SV8-p+(DkTGnA-%mgr9U&RS!}sgnfKUq zie7{4x@w+VuE8mq0*WEOua~u*2df!4%j!F7g4vN6B1_548#(UN^E=uzUOi_L#-}JBf^bdGM?_mT3i=92&)11x{}!B^{!L58hC z+)Vj}JOY6vzKks@%j$*l^!1(&zKdxJpL2KsvSn)I6w$ddj^I+M5z4c?R8%6AJ>2pT zd&w5o{5djZ9DjSbhN8B}sezqLEdQG|O2k-d3F{ud(Ie&3EX3U1` z>2h2Cp9FN=e-r-!mk$Su{>+8b4NI0N!CZDCOW)2$0rKAdva!w{7lT}|+0$trM!1$( zJp@NP(wF1(N^3DQI(5;6eQtg9s6R>=EYlboh@8_(R+-erzZf{r$bs;gNnRuDHs*}) zo-rj$USDg+~p% z$duRPWicLwu&VnDPB}xA9#E1#xT^HkqF*lLz^{;iBtqmD!8p0RlxsUvFmyGnX(LVe*6aEJXWn1Alg(zSFd8c z&!XlEb-7MgYH7SMgAQT30tJ6pm++&6T@L$jol z84D!3uj?SEgYB<(xh-EJ$)7(`WOIna1L)~K=h|eIBV})z%u)o2`rM*rS z@Ty|{J;3YA$bg^A>%lI>%R+f;uWQv6*c6MTyEXV;#yGSeaVNjrE~<(g2p2m19cK_f?NzGVPaHGo`AxURKU>gvL6+R|oh9la0Enxtpwa5F zVw&-Cr%Io|PderK*U!}CJV6rJFPE#K?YB}|dTW(|gK1{0DF9E#qrkF`jV(KzJ3k?B zEBV~0d6|Bi<=N0xT9YR^YBJxp4S9;LK8nQb_5H$oU@7PFs!^xpmn#O=qng=Sa@{d~ z5tU5V2BfnNjlurS%vEm`khykcx9e-N^WdxhRGU{6manjJQ^i|~V6Um0oZw(T)4_tn za-BXMcOyl^I1{SLglC@Gd^42V7`GBQ)daw0DVBBoIfzLowlmw6NEypG7b%6=1>r<) zTQyelojB^<&x?a2=ZO5rqA67>G| z$L9s1i8c1gSHrgh0zBVIa;jotr@+}%uZlDHn+gjQF?1{Y{-2XigCA%E{D>liZhxda zjdzV_$p?Q>R8(PvQBa#YPHyqaRkJ`$)*5$_zf4g6Ea;6@E79{;$9pY_%gwM+_kFV1 zb4ed&X^dpOTEFDy%8-3L*6QKc(AhtcE=XW5q*F=Xd_zD|R6X5XqkZP3j1^*dY=Ip& ze~QLRKasj=;Hcu2S=U|U>5r8?g?2*X<}I0mJrl{*-S*2?mCBbPI-SJw7rQY%E%(Xs z@VfUd>WUYq8%S&_8P@7Qva3@HR8u0b3arbWvXb_!sZYv1?`-Uu5vEAd}jmI;@Z_yqeHk9yX z@c8w&SO7P!v`9kDlo|f4sYI1;1A^7fxd?65Wx~AElyxKxDai&(P`@%`gr-x5^I@el z%Q8!;6d&9+if^SP<`>{|b!n7s%ROuQcSx8_#+P`Rq#UJW@!j}u0NNObiYg`UN%~8b8E#ZIH)oTsdovYe-!Fdd) zDHdxz5>8v2OB_$=y6gQF{O->tA@MU32OWw@Fed)RXtKJ|7{6(y{@1Azg-p&K3fLQA0HdSLi|TQz{PjF zB&09;KTH$?T(v~8D7$*F!sU1JUFT!631lnJhOyuKYzc=B96Ve+%0aw%i147DJ;6=E zH@lnL{o{dwC@e;#mpOo-4;KZMSM_<1bDh}*s-Ue^yzXBZ!L>OxJp7i53@J^bL0If`^>^OOvjuB@niocyr211Wd2O#jZwy;IXRSH&YwyK1t#N_+?O8Wif-sbN2c%E#ss znwDw4_{obgsO7BDS#I>)X0DumEJ6a`QE3TSZra;VGsg!98LuHRz6GmL9C45HjtZ_I zaH^19X>Bn58EmL>_dgN;HPbiSoZ2ds0lmiUw%AIG#bIU~;v-V@KDsf{y6n~I{J~s% z^bw&yPgoz{&w8w8foLIcBzRJfdm04Th{=LFZ@IY~{_s6Bfurw?F4`-g*;{uWhdmUV zRS5}oZN^*kff#V)UI^$K1*A?x>mLnF$I*M%E49Tum2v&WCTQ!U8`v)aP=Mw3n;pHc z{nO{L&!g;}dX`sa-E*_qumI6dZURDJrLNnQbr=TzPUH2gi?KHi>I&YqqgB7+1Bk=lz|ei*qp0v@fM>dvDO-K&mIVq6>y0HNA7bAG>=Z zIszmd!c!zee5_>S`|hQCqyVotWV~~@%>Z}@Hm9+@pp1k1QA6^2PHXCmiH^_Vp#F|S z$uhaP2G&E1w~lE4)}%X~yZ5`AQycjK2nv!ztKO`nMN6HNp@KQ5W|$34&^C4XsGU0_ z?xOj;wAc+GFHuuPPd|gCAkIr|PdmSbvJo`9QT>eryAujbNukH4hC(1i+?re%4+2=z zlGDXf!fE%HW~-)|*KuMcW;@f@HWf%KcfdjRr@}-a;r!>WD@+Uo*IWH-O02CQz1q0; z?)?_CA-1Cfg=Ub4DPP% zWq6Q0{d?qu!E!%su+c=n*m$zte$UFvF}pRB9GuRwhg*Qv@uEUK#7PuIl|29ZD-(9! zq{^$T?>^>pZT}G161W^YFHAsSVrzBp#R%eokWbgp>)1W~=)0+t7tGbo=@sDb5uSYW_BfDn@T$p zY0>Lk2}&k!$GN#*^k7-DQKKKL?PdQ{_5EVsJ{!@DVP4l}W{#i6rmCVq4>#vuQ(i<% zb_EO4-&+C(IUpDm_E?UNGtOs5#{TJyg1ucH4|h9fab-7~&y`xo2wi@k&w5tIY4>-^ z!F?-=z6~r=oX#8OZH)!043(HTesU6}NLkPXD2c4ggu!E6wR%>>A5e9w3*;ev7vO2) z;uB!rSj%~wQklrTXnr)aG7Z7EXdA8#q@H9)wF3A~W=8QbJ!*~Xa0D)c@a(%ypXmNT zvSueh3%8$K`^-f~ol-}t3WX_9!m&MF^as~XOYhIw*N-6FBWrsE%nI|kQ1n#Kl3WZ- zj@AH1mZ@I;k2U32!K#wffiK@SWDqA_@3y~IKj`X)u>11Xf6D`JY(n@;8W!3cirB-+ z*W5XSBM9t4rv!Z1Uh7gHOu8h~0g~C2?I!YYhGCMZERCB7a50uo=Pcoq;zQqPPMAn* zCV|Xy6CJw&xdO$h^epkzOKRe9Qi~+Wgp}wro@PZK0zq?yRCa(4zOQLn+u$*zg+BTW zf~$W)qeNvWhZjWQ{``6~ClK+5Y)t;Jo?gN)Am~Dq`5g%Py4Q0sRro=Ohj-@P0oM39|kHRariL_5I^f!1j01aooNzI>bCZ!d}Y6C`&%Wj)al z0+?AYPev+8dU;d3^oDr-;vZp^^=XOi$WRgC8}ExNn|syM*nryVkJ_r4;bA&Do*%J2 z(;^7h?V7|D!nDZrBGSBbx-}f3j0v%W@vu5?fh5?Py{ORs?w$?Vvii#z3bqTqP%FVz z7c#SkNRT0|wUbkf-f(D>k23vWTm8&>WE&HaWyw}$ifUxyR8%jUWSN@siK3O4(6{|z z0af39Aw%IVzPV6phPk3u7vbPFGIi59P&-^vL4pu{>nKhBI@L?yKmGRE0|sjWx|GvLey?f0gSd70;+4^mS^j?EZK_BJ^>3KM2kVMDY*s34eY&@J%k;rB6wT4uttBQ(>XnQ5imRi+)yl2&kQKy-UJt;aolw1IOd(k9)l>f@W5dWu}f zLzC7-NI`qpBNcIC10sQqR@lEHK@Tm6+J5i<<$R?LTfWARN-@QIcv=`8< zm8I4}Ap-jZE2lV{XLy~SJwTB_s-zt~?#X^<(OG+TNXmjxW}L7{+Vv`s)an$EVG~u5^Hb7* z((2h6GIt1)Eb%FPEVuQ`n{a2Gb3J8cC+fEPV|N&6!Xf~y*5)xGH&XI^D)dPVLzR* zOLZ+WA8hGIa%kl|T>TMH0Hyj?ZaxB3ZJdY-zRfXnf=4~Wd_U^Nlv@@wb23YK>e!g9 z=fp&_YXP08B2Iz$)`d-`%aN>ih8-|n7VmS5uXQC0dGL1zLkIfIpu=6IaM0$gN@xc%Pb2)3jEQ;P8; zC8dVIwg-$pQQE)B(ZVLB*O?n+2y#f@PaBQj6dh`lA7=tOtWNi+Aa0NlF|3^nYQ9JM zZUNX*c`Q8J(Q#%5@JT!IeJjNoDlihis=+Nb^hEud2_B9YeYq_-NIN^|R{-u=Ibjj% zHM|wYk*S1F`jLQy1z=a?ytFh%x@2osD}r*}$Ky6{cxh}{JD>K~yzBH!J0V@LYA-R8 zc}fa@ItrGws>@lKx|E>Wwtr24x)p4Wrr$$0XA`^w8bV?t4}exlk(A0>K{cpFE2erg z$A{I(y5!vo`315E)2t71c_|<5>$YR`-{j^2EdxOS6|sa577Yc3hO}-A$;e> zpzR(V(Ko62Hzs&-%i!Bygj{9}$T1P*a1s_ET+_MnO})G#?+Haru14@f!#vB&;J&Ge zmSOHNFiab*9Sl!N#Q;|bi~jdl)i{$Hg{|6YysLjFQl+0-M9wjp^+;Uj@ygPW-&Rd+ zog1OX)bj3r+Acv@>FSub+MYeVPh;h^O8JHFMkP1Vg3XA{%qHoK8F;L~wqOZ3`u%_4i>o)<4>gBVD|&wJ^NX=3 z2nyIiNbxJp)@Bhi6Rd9ql7i@+xBQ>k0OVb^t@nh)s&#Ha@Jb}Src)rgHb(Y)r>X;0 zaYaKQ&|Ph=HKeM$IQ7tmn<5=7g?2g{e+Kb9+;xYZAeA=435Sy>zXeCuc3xzYer^LU zhTpD{v}6*iMpN9M!DO41jrLZ}*YaI&&213!j!pY)!claRnAw0Uc8Qj@#2@t>g~tYgtKSiB8<4*U4L$Y(D5jST~sG}rCCF^J8V)ZjoYxVBh!U}T| zo2*}*IV9n7^{{~l$lOM{$8E1YanTUa+L4`HjN#QthRtpHMHrN!MpKBhRCGY-%&&fwVo1U@_q zx^428SO6dTj*|lD|1B)|cm$YzptnC}X&`IbxuA!>noOdcp#3UVfjCpA#-uwn>@1te zvYPY^xYpAj)1|qsZ~pkmuOuHYQwLEbUpk-5XCQh$b&$#Vib;PPIAVoSqdlqaqLBax z4)s~k)fPgleeX~V!A`BL*hTt&u$PCL_EpvW>AB-8?$ZrU^ZQ}wP-O&5{}DvmM*!w2 zis+z@1#qz14RwClMrUiE?iO^#XT+*NOEQ4<3K|M7N`nM}e&5tbfozVccR_RzsVWwI z@kJ%d%b7O;9AnjKeV-kZ?6Y+bsH3C;7vuh0Qn$vyJ=$Fmm)FJ)XnpeG_kCU%3h#vf zu!SekKmfH}>I(@e@bf54VPj+yDRo diff --git a/charts/v1.26.1/azurefile-csi-driver/Chart.yaml b/charts/v1.26.1/azurefile-csi-driver/Chart.yaml deleted file mode 100644 index 630811bca8..0000000000 --- a/charts/v1.26.1/azurefile-csi-driver/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -appVersion: v1.26.1 -description: Azure File Container Storage Interface (CSI) Storage Plugin -name: azurefile-csi-driver -version: v1.26.1 diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/NOTES.txt b/charts/v1.26.1/azurefile-csi-driver/templates/NOTES.txt deleted file mode 100644 index 3fadd8ad36..0000000000 --- a/charts/v1.26.1/azurefile-csi-driver/templates/NOTES.txt +++ /dev/null @@ -1,5 +0,0 @@ -The Azure File CSI Driver is getting deployed to your cluster. - -To check Azure File CSI Driver pods status, please run: - - kubectl --namespace={{ .Release.Namespace }} get pods --selector="release={{ .Release.Name }}" --watch diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/_helpers.tpl b/charts/v1.26.1/azurefile-csi-driver/templates/_helpers.tpl deleted file mode 100644 index b1bf4dc1b6..0000000000 --- a/charts/v1.26.1/azurefile-csi-driver/templates/_helpers.tpl +++ /dev/null @@ -1,49 +0,0 @@ -{{/* vim: set filetype=mustache: */}} - -{{/* Expand the name of the chart.*/}} -{{- define "azurefile.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "azurefile.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Common selectors. -*/}} -{{- define "azurefile.selectorLabels" -}} -app.kubernetes.io/name: {{ template "azurefile.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end -}} - -{{/* -Common labels. -*/}} -{{- define "azurefile.labels" -}} -{{- include "azurefile.selectorLabels" . }} -app.kubernetes.io/component: csi-driver -app.kubernetes.io/part-of: {{ template "azurefile.name" . }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -helm.sh/chart: {{ template "azurefile.chart" . }} -{{- if .Values.customLabels }} -{{ toYaml .Values.customLabels }} -{{- end }} -{{- end -}} - - -{{/* pull secrets for containers */}} -{{- define "azurefile.pullSecrets" -}} -{{- if .Values.imagePullSecrets }} -imagePullSecrets: -{{- range .Values.imagePullSecrets }} - - name: {{ . }} -{{- end }} -{{- end }} -{{- end -}} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/crd-csi-snapshot.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/crd-csi-snapshot.yaml deleted file mode 100644 index b0e29453c5..0000000000 --- a/charts/v1.26.1/azurefile-csi-driver/templates/crd-csi-snapshot.yaml +++ /dev/null @@ -1,661 +0,0 @@ -{{- if .Values.snapshot.enabled -}} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.4.0 - api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" - creationTimestamp: null - name: volumesnapshots.snapshot.storage.k8s.io -spec: - group: snapshot.storage.k8s.io - names: - kind: VolumeSnapshot - listKind: VolumeSnapshotList - plural: volumesnapshots - shortNames: - - vs - singular: volumesnapshot - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: Indicates if the snapshot is ready to be used to restore a volume. - jsonPath: .status.readyToUse - name: ReadyToUse - type: boolean - - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. - jsonPath: .spec.source.persistentVolumeClaimName - name: SourcePVC - type: string - - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. - jsonPath: .spec.source.volumeSnapshotContentName - name: SourceSnapshotContent - type: string - - description: Represents the minimum size of volume required to rehydrate from this snapshot. - jsonPath: .status.restoreSize - name: RestoreSize - type: string - - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. - jsonPath: .spec.volumeSnapshotClassName - name: SnapshotClass - type: string - - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. - jsonPath: .status.boundVolumeSnapshotContentName - name: SnapshotContent - type: string - - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. - jsonPath: .status.creationTime - name: CreationTime - type: date - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1 - schema: - openAPIV3Schema: - description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - spec: - description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' - properties: - source: - description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. - properties: - persistentVolumeClaimName: - description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. - type: string - volumeSnapshotContentName: - description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. - type: string - type: object - oneOf: - - required: ["persistentVolumeClaimName"] - - required: ["volumeSnapshotContentName"] - volumeSnapshotClassName: - description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' - type: string - required: - - source - type: object - status: - description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. - properties: - boundVolumeSnapshotContentName: - description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' - type: string - creationTime: - description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. - format: date-time - type: string - error: - description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurrs during the snapshot creation. Upon success, this error field will be cleared. - properties: - message: - description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' - type: string - time: - description: time is the timestamp when the error was encountered. - format: date-time - type: string - type: object - readyToUse: - description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. - type: boolean - restoreSize: - type: string - description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} - - additionalPrinterColumns: - - description: Indicates if the snapshot is ready to be used to restore a volume. - jsonPath: .status.readyToUse - name: ReadyToUse - type: boolean - - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. - jsonPath: .spec.source.persistentVolumeClaimName - name: SourcePVC - type: string - - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. - jsonPath: .spec.source.volumeSnapshotContentName - name: SourceSnapshotContent - type: string - - description: Represents the minimum size of volume required to rehydrate from this snapshot. - jsonPath: .status.restoreSize - name: RestoreSize - type: string - - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. - jsonPath: .spec.volumeSnapshotClassName - name: SnapshotClass - type: string - - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. - jsonPath: .status.boundVolumeSnapshotContentName - name: SnapshotContent - type: string - - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. - jsonPath: .status.creationTime - name: CreationTime - type: date - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1beta1 - # This indicates the v1beta1 version of the custom resource is deprecated. - # API requests to this version receive a warning in the server response. - deprecated: true - # This overrides the default warning returned to clients making v1beta1 API requests. - deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshot is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshot" - schema: - openAPIV3Schema: - description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - spec: - description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' - properties: - source: - description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. - properties: - persistentVolumeClaimName: - description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. - type: string - volumeSnapshotContentName: - description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. - type: string - type: object - volumeSnapshotClassName: - description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' - type: string - required: - - source - type: object - status: - description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. - properties: - boundVolumeSnapshotContentName: - description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' - type: string - creationTime: - description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. - format: date-time - type: string - error: - description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurrs during the snapshot creation. Upon success, this error field will be cleared. - properties: - message: - description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' - type: string - time: - description: time is the timestamp when the error was encountered. - format: date-time - type: string - type: object - readyToUse: - description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. - type: boolean - restoreSize: - type: string - description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - required: - - spec - type: object - served: true - storage: false - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] - ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.4.0 - api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" - creationTimestamp: null - name: volumesnapshotclasses.snapshot.storage.k8s.io -spec: - group: snapshot.storage.k8s.io - names: - kind: VolumeSnapshotClass - listKind: VolumeSnapshotClassList - plural: volumesnapshotclasses - shortNames: - - vsclass - - vsclasses - singular: volumesnapshotclass - scope: Cluster - versions: - - additionalPrinterColumns: - - jsonPath: .driver - name: Driver - type: string - - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. - jsonPath: .deletionPolicy - name: DeletionPolicy - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1 - schema: - openAPIV3Schema: - description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - deletionPolicy: - description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. - enum: - - Delete - - Retain - type: string - driver: - description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - parameters: - additionalProperties: - type: string - description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. - type: object - required: - - deletionPolicy - - driver - type: object - served: true - storage: true - subresources: {} - - additionalPrinterColumns: - - jsonPath: .driver - name: Driver - type: string - - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. - jsonPath: .deletionPolicy - name: DeletionPolicy - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1beta1 - # This indicates the v1beta1 version of the custom resource is deprecated. - # API requests to this version receive a warning in the server response. - deprecated: true - # This overrides the default warning returned to clients making v1beta1 API requests. - deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotClass is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotClass" - schema: - openAPIV3Schema: - description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - deletionPolicy: - description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. - enum: - - Delete - - Retain - type: string - driver: - description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - parameters: - additionalProperties: - type: string - description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. - type: object - required: - - deletionPolicy - - driver - type: object - served: true - storage: false - subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] - ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.4.0 - api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/419" - creationTimestamp: null - name: volumesnapshotcontents.snapshot.storage.k8s.io -spec: - group: snapshot.storage.k8s.io - names: - kind: VolumeSnapshotContent - listKind: VolumeSnapshotContentList - plural: volumesnapshotcontents - shortNames: - - vsc - - vscs - singular: volumesnapshotcontent - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Indicates if the snapshot is ready to be used to restore a volume. - jsonPath: .status.readyToUse - name: ReadyToUse - type: boolean - - description: Represents the complete size of the snapshot in bytes - jsonPath: .status.restoreSize - name: RestoreSize - type: integer - - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. - jsonPath: .spec.deletionPolicy - name: DeletionPolicy - type: string - - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. - jsonPath: .spec.driver - name: Driver - type: string - - description: Name of the VolumeSnapshotClass to which this snapshot belongs. - jsonPath: .spec.volumeSnapshotClassName - name: VolumeSnapshotClass - type: string - - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. - jsonPath: .spec.volumeSnapshotRef.name - name: VolumeSnapshot - type: string - - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. - jsonPath: .spec.volumeSnapshotRef.namespace - name: VolumeSnapshotNamespace - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1 - schema: - openAPIV3Schema: - description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - spec: - description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. - properties: - deletionPolicy: - description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. - enum: - - Delete - - Retain - type: string - driver: - description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. - type: string - source: - description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. - properties: - snapshotHandle: - description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. - type: string - volumeHandle: - description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. - type: string - type: object - oneOf: - - required: ["snapshotHandle"] - - required: ["volumeHandle"] - volumeSnapshotClassName: - description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. - type: string - volumeSnapshotRef: - description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. - properties: - apiVersion: - description: API version of the referent. - type: string - fieldPath: - description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' - type: string - kind: - description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' - type: string - resourceVersion: - description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' - type: string - uid: - description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' - type: string - type: object - required: - - deletionPolicy - - driver - - source - - volumeSnapshotRef - type: object - status: - description: status represents the current information of a snapshot. - properties: - creationTime: - description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. - format: int64 - type: integer - error: - description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. - properties: - message: - description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' - type: string - time: - description: time is the timestamp when the error was encountered. - format: date-time - type: string - type: object - readyToUse: - description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. - type: boolean - restoreSize: - description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. - format: int64 - minimum: 0 - type: integer - snapshotHandle: - description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. - type: string - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} - - additionalPrinterColumns: - - description: Indicates if the snapshot is ready to be used to restore a volume. - jsonPath: .status.readyToUse - name: ReadyToUse - type: boolean - - description: Represents the complete size of the snapshot in bytes - jsonPath: .status.restoreSize - name: RestoreSize - type: integer - - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. - jsonPath: .spec.deletionPolicy - name: DeletionPolicy - type: string - - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. - jsonPath: .spec.driver - name: Driver - type: string - - description: Name of the VolumeSnapshotClass to which this snapshot belongs. - jsonPath: .spec.volumeSnapshotClassName - name: VolumeSnapshotClass - type: string - - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. - jsonPath: .spec.volumeSnapshotRef.name - name: VolumeSnapshot - type: string - - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. - jsonPath: .spec.volumeSnapshotRef.namespace - name: VolumeSnapshotNamespace - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1beta1 - # This indicates the v1beta1 version of the custom resource is deprecated. - # API requests to this version receive a warning in the server response. - deprecated: true - # This overrides the default warning returned to clients making v1beta1 API requests. - deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotContent is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotContent" - schema: - openAPIV3Schema: - description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - spec: - description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. - properties: - deletionPolicy: - description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. - enum: - - Delete - - Retain - type: string - driver: - description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. - type: string - source: - description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. - properties: - snapshotHandle: - description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. - type: string - volumeHandle: - description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. - type: string - type: object - volumeSnapshotClassName: - description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. - type: string - volumeSnapshotRef: - description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. - properties: - apiVersion: - description: API version of the referent. - type: string - fieldPath: - description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' - type: string - kind: - description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' - type: string - resourceVersion: - description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' - type: string - uid: - description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' - type: string - type: object - required: - - deletionPolicy - - driver - - source - - volumeSnapshotRef - type: object - status: - description: status represents the current information of a snapshot. - properties: - creationTime: - description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. - format: int64 - type: integer - error: - description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. - properties: - message: - description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' - type: string - time: - description: time is the timestamp when the error was encountered. - format: date-time - type: string - type: object - readyToUse: - description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. - type: boolean - restoreSize: - description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. - format: int64 - minimum: 0 - type: integer - snapshotHandle: - description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. - type: string - type: object - required: - - spec - type: object - served: true - storage: false - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] -{{- end -}} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-controller.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-controller.yaml deleted file mode 100644 index 23381ec245..0000000000 --- a/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-controller.yaml +++ /dev/null @@ -1,243 +0,0 @@ -kind: Deployment -apiVersion: apps/v1 -metadata: - name: {{ .Values.controller.name }} - namespace: {{ .Release.Namespace }} - labels: - app: {{ .Values.controller.name }} - {{- include "azurefile.labels" . | nindent 4 }} -{{- with .Values.controller.labels }} -{{ . | toYaml | indent 4 }} -{{- end }} -{{- with .Values.controller.annotations }} - annotations: -{{ . | toYaml | indent 4 }} -{{- end }} -spec: - replicas: {{ .Values.controller.replicas }} - selector: - matchLabels: - {{- include "azurefile.selectorLabels" . | nindent 6 }} - app: {{ .Values.controller.name }} - template: - metadata: - labels: - {{- include "azurefile.labels" . | nindent 8 }} - app: {{ .Values.controller.name }} -{{- with .Values.controller.podLabels }} -{{ toYaml . | indent 8 }} -{{- end }} -{{- with .Values.controller.podAnnotations }} - annotations: -{{ toYaml . | indent 8 }} -{{- end }} - spec: - hostNetwork: {{ .Values.controller.hostNetwork }} - serviceAccountName: {{ .Values.serviceAccount.controller }} - nodeSelector: - kubernetes.io/os: linux -{{- with .Values.controller.nodeSelector }} -{{ toYaml . | indent 8 }} -{{- end }} - {{- if .Values.controller.runOnMaster}} - node-role.kubernetes.io/master: "" - {{- end}} - {{- if .Values.controller.runOnControlPlane}} - node-role.kubernetes.io/control-plane: "" - {{- end}} - priorityClassName: system-cluster-critical -{{- with .Values.controller.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} -{{- end }} -{{- with .Values.controller.affinity }} - affinity: -{{ toYaml . | indent 8 }} -{{- end }} - {{- if .Values.imagePullSecrets }} - imagePullSecrets: -{{ toYaml .Values.imagePullSecrets | indent 8 }} - {{- end }} - containers: - - name: csi-provisioner -{{- if hasPrefix "/" .Values.image.csiProvisioner.repository }} - image: "{{ .Values.image.baseRepo }}{{ .Values.image.csiProvisioner.repository }}:{{ .Values.image.csiProvisioner.tag }}" -{{- else }} - image: "{{ .Values.image.csiProvisioner.repository }}:{{ .Values.image.csiProvisioner.tag }}" -{{- end }} - args: - - "-v=2" - - "--csi-address=$(ADDRESS)" - - "--leader-election" - - "--leader-election-namespace={{ .Release.Namespace }}" - - "--timeout=300s" - - "--extra-create-metadata=true" - - "--kube-api-qps=50" - - "--kube-api-burst=100" - env: - - name: ADDRESS - value: /csi/csi.sock - imagePullPolicy: {{ .Values.image.csiProvisioner.pullPolicy }} - volumeMounts: - - mountPath: /csi - name: socket-dir - resources: {{- toYaml .Values.controller.resources.csiProvisioner | nindent 12 }} - - name: csi-attacher -{{- if hasPrefix "/" .Values.image.csiAttacher.repository }} - image: "{{ .Values.image.baseRepo }}{{ .Values.image.csiAttacher.repository }}:{{ .Values.image.csiAttacher.tag }}" -{{- else }} - image: "{{ .Values.image.csiAttacher.repository }}:{{ .Values.image.csiAttacher.tag }}" -{{- end }} - args: - - "-v=2" - - "-csi-address=$(ADDRESS)" - - "-timeout=120s" - - "-leader-election" - - "--leader-election-namespace={{ .Release.Namespace }}" - - "--kube-api-qps=50" - - "--kube-api-burst=100" - env: - - name: ADDRESS - value: /csi/csi.sock - imagePullPolicy: {{ .Values.image.csiAttacher.pullPolicy }} - volumeMounts: - - mountPath: /csi - name: socket-dir - resources: {{- toYaml .Values.controller.resources.csiAttacher | nindent 12 }} - - name: csi-snapshotter -{{- if hasPrefix "/" .Values.snapshot.image.csiSnapshotter.repository }} - image: "{{ .Values.image.baseRepo }}{{ .Values.snapshot.image.csiSnapshotter.repository }}:{{ .Values.snapshot.image.csiSnapshotter.tag }}" -{{- else }} - image: "{{ .Values.snapshot.image.csiSnapshotter.repository }}:{{ .Values.snapshot.image.csiSnapshotter.tag }}" -{{- end }} - args: - - "-csi-address=$(ADDRESS)" - - "-leader-election" - - "--leader-election-namespace={{ .Release.Namespace }}" - - "-v=2" - env: - - name: ADDRESS - value: /csi/csi.sock - volumeMounts: - - name: socket-dir - mountPath: /csi - resources: {{- toYaml .Values.controller.resources.csiSnapshotter | nindent 12 }} - - name: csi-resizer -{{- if hasPrefix "/" .Values.image.csiResizer.repository }} - image: "{{ .Values.image.baseRepo }}{{ .Values.image.csiResizer.repository }}:{{ .Values.image.csiResizer.tag }}" -{{- else }} - image: "{{ .Values.image.csiResizer.repository }}:{{ .Values.image.csiResizer.tag }}" -{{- end }} - args: - - "-csi-address=$(ADDRESS)" - - "-v=2" - - "-leader-election" - - "--leader-election-namespace={{ .Release.Namespace }}" - - '-handle-volume-inuse-error=false' - - '-timeout=120s' - - '-feature-gates=RecoverVolumeExpansionFailure=true' - env: - - name: ADDRESS - value: /csi/csi.sock - imagePullPolicy: {{ .Values.image.csiResizer.pullPolicy }} - volumeMounts: - - name: socket-dir - mountPath: /csi - resources: {{- toYaml .Values.controller.resources.csiResizer | nindent 12 }} - - name: liveness-probe -{{- if hasPrefix "/" .Values.image.livenessProbe.repository }} - image: "{{ .Values.image.baseRepo }}{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" -{{- else }} - image: "{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" -{{- end }} - args: - - --csi-address=/csi/csi.sock - - --probe-timeout=3s - - --health-port={{ .Values.controller.livenessProbe.healthPort }} - - --v=2 - imagePullPolicy: {{ .Values.image.livenessProbe.pullPolicy }} - volumeMounts: - - name: socket-dir - mountPath: /csi - resources: {{- toYaml .Values.controller.resources.livenessProbe | nindent 12 }} - - name: azurefile -{{- if hasPrefix "/" .Values.image.azurefile.repository }} - image: "{{ .Values.image.baseRepo }}{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" -{{- else }} - image: "{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" -{{- end }} - args: - - "--v={{ .Values.controller.logLevel }}" - - "--endpoint=$(CSI_ENDPOINT)" - - "--metrics-address=0.0.0.0:{{ .Values.controller.metricsPort }}" - - "--kubeconfig={{ .Values.controller.kubeconfig }}" - - "--drivername={{ .Values.driver.name }}" - - "--cloud-config-secret-name={{ .Values.controller.cloudConfigSecretName }}" - - "--cloud-config-secret-namespace={{ .Values.controller.cloudConfigSecretNamespace }}" - - "--custom-user-agent={{ .Values.driver.customUserAgent }}" - - "--user-agent-suffix={{ .Values.driver.userAgentSuffix }}" - - "--allow-empty-cloud-config={{ .Values.controller.allowEmptyCloudConfig }}" - ports: - - containerPort: {{ .Values.controller.livenessProbe.healthPort }} - name: healthz - protocol: TCP - - containerPort: {{ .Values.controller.metricsPort }} - name: metrics - protocol: TCP - livenessProbe: - failureThreshold: 5 - httpGet: - path: /healthz - port: healthz - initialDelaySeconds: 30 - timeoutSeconds: 10 - periodSeconds: 30 - env: - - name: AZURE_CREDENTIAL_FILE - valueFrom: - configMapKeyRef: - name: azure-cred-file - key: path - optional: true - - name: CSI_ENDPOINT - value: unix:///csi/csi.sock - {{- if ne .Values.driver.httpsProxy "" }} - - name: HTTPS_PROXY - value: {{ .Values.driver.httpsProxy }} - {{- end }} - {{- if ne .Values.driver.httpProxy "" }} - - name: HTTP_PROXY - value: {{ .Values.driver.httpProxy }} - {{- end }} - - name: AZURE_GO_SDK_LOG_LEVEL - value: {{ .Values.driver.azureGoSDKLogLevel }} - imagePullPolicy: {{ .Values.image.azurefile.pullPolicy }} - volumeMounts: - - mountPath: /csi - name: socket-dir - - mountPath: /etc/kubernetes/ - name: azure-cred - {{- if eq .Values.linux.distro "fedora" }} - - name: ssl - mountPath: /etc/ssl/certs - readOnly: true - - name: ssl-pki - mountPath: /etc/pki/ca-trust/extracted - readOnly: true - {{- end }} - resources: {{- toYaml .Values.controller.resources.azurefile | nindent 12 }} - volumes: - - name: socket-dir - emptyDir: {} - - name: azure-cred - hostPath: - path: /etc/kubernetes/ - type: DirectoryOrCreate - {{- if eq .Values.linux.distro "fedora" }} - - name: ssl - hostPath: - path: /etc/ssl/certs - - name: ssl-pki - hostPath: - path: /etc/pki/ca-trust/extracted - {{- end }} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-driver.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-driver.yaml deleted file mode 100644 index e1facb056a..0000000000 --- a/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-driver.yaml +++ /dev/null @@ -1,17 +0,0 @@ ---- -apiVersion: storage.k8s.io/v1 -kind: CSIDriver -metadata: - name: {{ .Values.driver.name }} - labels: - {{- include "azurefile.labels" . | nindent 4 }} - annotations: - csiDriver: "{{ .Values.image.azurefile.tag }}" - snapshot: "{{ .Values.snapshot.image.csiSnapshotter.tag }}" -spec: - attachRequired: {{ .Values.controller.attachRequired }} - podInfoOnMount: true - volumeLifecycleModes: - - Persistent - - Ephemeral - fsGroupPolicy: ReadWriteOnceWithFSType diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml deleted file mode 100644 index 813859aee0..0000000000 --- a/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node-windows.yaml +++ /dev/null @@ -1,222 +0,0 @@ -{{- if .Values.windows.enabled}} -kind: DaemonSet -apiVersion: apps/v1 -metadata: - name: {{ .Values.windows.dsName }} - namespace: {{ .Release.Namespace }} - labels: - app: {{ .Values.windows.dsName }} - {{- include "azurefile.labels" . | nindent 4 }} -{{- with .Values.windows.labels }} -{{ . | toYaml | indent 4 }} -{{- end }} -{{- with .Values.windows.annotations }} - annotations: -{{ . | toYaml | indent 4 }} -{{- end }} -spec: - updateStrategy: - rollingUpdate: - maxUnavailable: {{ .Values.node.maxUnavailable }} - type: RollingUpdate - selector: - matchLabels: - app: {{ .Values.windows.dsName }} - {{- include "azurefile.selectorLabels" . | nindent 6 }} - template: - metadata: - labels: - app: {{ .Values.windows.dsName }} - {{- include "azurefile.labels" . | nindent 8 }} -{{- with .Values.windows.podLabels }} -{{ toYaml . | indent 8 }} -{{- end }} -{{- with .Values.windows.podAnnotations }} - annotations: -{{ toYaml . | indent 8 }} -{{- end }} - spec: - serviceAccountName: {{ .Values.serviceAccount.node }} -{{- with .Values.windows.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} -{{- end }} - nodeSelector: - kubernetes.io/os: windows -{{- with .Values.windows.nodeSelector }} -{{ toYaml . | indent 8 }} -{{- end }} - affinity: -{{- with .Values.windows.affinity }} -{{ toYaml . | indent 8 }} -{{- end }} - nodeAffinity: -{{ toYaml .Values.windows.nodeAffinity | indent 10 }} - priorityClassName: system-node-critical - {{- if .Values.imagePullSecrets }} - imagePullSecrets: -{{ toYaml .Values.imagePullSecrets | indent 8 }} - {{- end }} - containers: - - name: liveness-probe - volumeMounts: - - mountPath: C:\csi - name: plugin-dir -{{- if hasPrefix "/" .Values.image.livenessProbe.repository }} - image: "{{ .Values.image.baseRepo }}{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" -{{- else }} - image: "{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" -{{- end }} - args: - - "--csi-address=$(CSI_ENDPOINT)" - - "--probe-timeout=3s" - - "--health-port={{ .Values.node.livenessProbe.healthPort }}" - - "--v=2" - env: - - name: CSI_ENDPOINT - value: unix://C:\\csi\\csi.sock - imagePullPolicy: {{ .Values.image.livenessProbe.pullPolicy }} - resources: {{- toYaml .Values.windows.resources.livenessProbe | nindent 12 }} - - name: node-driver-registrar -{{- if hasPrefix "/" .Values.image.nodeDriverRegistrar.repository }} - image: "{{ .Values.image.baseRepo }}{{ .Values.image.nodeDriverRegistrar.repository }}:{{ .Values.image.nodeDriverRegistrar.tag }}" -{{- else }} - image: "{{ .Values.image.nodeDriverRegistrar.repository }}:{{ .Values.image.nodeDriverRegistrar.tag }}" -{{- end }} - args: - - "--csi-address=$(CSI_ENDPOINT)" - - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" - - "--v=2" - livenessProbe: - exec: - command: - - /csi-node-driver-registrar.exe - - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) - - --mode=kubelet-registration-probe - initialDelaySeconds: 60 - timeoutSeconds: 30 - env: - - name: CSI_ENDPOINT - value: unix://C:\\csi\\csi.sock - - name: DRIVER_REG_SOCK_PATH - value: C:\\var\\lib\\kubelet\\plugins\\{{ .Values.driver.name }}\\csi.sock - - name: KUBE_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - imagePullPolicy: {{ .Values.image.nodeDriverRegistrar.pullPolicy }} - volumeMounts: - - name: kubelet-dir - mountPath: "C:\\var\\lib\\kubelet" - - name: plugin-dir - mountPath: C:\csi - - name: registration-dir - mountPath: C:\registration - resources: {{- toYaml .Values.windows.resources.nodeDriverRegistrar | nindent 12 }} - - name: azurefile -{{- if hasPrefix "/" .Values.image.azurefile.repository }} - image: "{{ .Values.image.baseRepo }}{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" -{{- else }} - image: "{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" -{{- end }} - args: - - "--v={{ .Values.node.logLevel }}" - - "--endpoint=$(CSI_ENDPOINT)" - - "--nodeid=$(KUBE_NODE_NAME)" - - "--metrics-address=0.0.0.0:{{ .Values.node.metricsPort }}" - - "--kubeconfig={{ .Values.windows.kubeconfig }}" - - "--drivername={{ .Values.driver.name }}" - - "--cloud-config-secret-name={{ .Values.node.cloudConfigSecretName }}" - - "--cloud-config-secret-namespace={{ .Values.node.cloudConfigSecretNamespace }}" - - "--custom-user-agent={{ .Values.driver.customUserAgent }}" - - "--user-agent-suffix={{ .Values.driver.userAgentSuffix }}" - - "--allow-empty-cloud-config={{ .Values.node.allowEmptyCloudConfig }}" - - "--enable-get-volume-stats={{ .Values.feature.enableGetVolumeStats }}" - - "--allow-inline-volume-key-access-with-identity={{ .Values.node.allowInlineVolumeKeyAccessWithIdentity }}" - ports: - - containerPort: {{ .Values.node.livenessProbe.healthPort }} - name: healthz - protocol: TCP - livenessProbe: - failureThreshold: 5 - httpGet: - path: /healthz - port: healthz - initialDelaySeconds: 30 - timeoutSeconds: 10 - periodSeconds: 30 - env: - - name: AZURE_CREDENTIAL_FILE - valueFrom: - configMapKeyRef: - name: azure-cred-file - key: path-windows - optional: true - - name: CSI_ENDPOINT - value: unix://C:\\csi\\csi.sock - {{- if ne .Values.driver.httpsProxy "" }} - - name: HTTPS_PROXY - value: {{ .Values.driver.httpsProxy }} - {{- end }} - {{- if ne .Values.driver.httpProxy "" }} - - name: HTTP_PROXY - value: {{ .Values.driver.httpProxy }} - {{- end }} - - name: KUBE_NODE_NAME - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: spec.nodeName - - name: AZURE_GO_SDK_LOG_LEVEL - value: {{ .Values.driver.azureGoSDKLogLevel }} - imagePullPolicy: {{ .Values.image.pullPolicy }} - volumeMounts: - - name: kubelet-dir - mountPath: "C:\\var\\lib\\kubelet" - - name: plugin-dir - mountPath: C:\csi - - name: azure-config - mountPath: C:\k - - name: csi-proxy-fs-pipe-v1 - mountPath: \\.\pipe\csi-proxy-filesystem-v1 - - name: csi-proxy-smb-pipe-v1 - mountPath: \\.\pipe\csi-proxy-smb-v1 - # these paths are still included for compatibility, they're used - # only if the node has still the beta version of the CSI proxy - - name: csi-proxy-fs-pipe-v1beta1 - mountPath: \\.\pipe\csi-proxy-filesystem-v1beta1 - - name: csi-proxy-smb-pipe-v1beta1 - mountPath: \\.\pipe\csi-proxy-smb-v1beta1 - resources: {{- toYaml .Values.windows.resources.azurefile | nindent 12 }} - volumes: - - name: csi-proxy-fs-pipe-v1 - hostPath: - path: \\.\pipe\csi-proxy-filesystem-v1 - - name: csi-proxy-smb-pipe-v1 - hostPath: - path: \\.\pipe\csi-proxy-smb-v1 - # these paths are still included for compatibility, they're used - # only if the node has still the beta version of the CSI proxy - - name: csi-proxy-fs-pipe-v1beta1 - hostPath: - path: \\.\pipe\csi-proxy-filesystem-v1beta1 - - name: csi-proxy-smb-pipe-v1beta1 - hostPath: - path: \\.\pipe\csi-proxy-smb-v1beta1 - - name: registration-dir - hostPath: - path: {{ .Values.windows.kubelet }}\plugins_registry\ - type: Directory - - name: kubelet-dir - hostPath: - path: {{ .Values.windows.kubelet }}\ - type: Directory - - name: plugin-dir - hostPath: - path: {{ .Values.windows.kubelet }}\plugins\{{ .Values.driver.name }}\ - type: DirectoryOrCreate - - name: azure-config - hostPath: - path: C:\k - type: Directory -{{- end -}} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node.yaml deleted file mode 100644 index 60a746eb5d..0000000000 --- a/charts/v1.26.1/azurefile-csi-driver/templates/csi-azurefile-node.yaml +++ /dev/null @@ -1,217 +0,0 @@ -{{- if .Values.linux.enabled}} -kind: DaemonSet -apiVersion: apps/v1 -metadata: - name: {{ .Values.linux.dsName }} - namespace: {{ .Release.Namespace }} - labels: - app: {{ .Values.linux.dsName }} - {{- include "azurefile.labels" . | nindent 4 }} -{{- with .Values.linux.labels }} -{{ . | toYaml | indent 4 }} -{{- end }} -{{- with .Values.linux.annotations }} - annotations: -{{ . | toYaml | indent 4 }} -{{- end }} -spec: - updateStrategy: - rollingUpdate: - maxUnavailable: {{ .Values.node.maxUnavailable }} - type: RollingUpdate - selector: - matchLabels: - app: {{ .Values.linux.dsName }} - {{- include "azurefile.selectorLabels" . | nindent 6 }} - template: - metadata: - labels: - app: {{ .Values.linux.dsName }} - {{- include "azurefile.labels" . | nindent 8 }} -{{- with .Values.linux.podLabels }} -{{ toYaml . | indent 8 }} -{{- end }} -{{- with .Values.linux.podAnnotations }} - annotations: -{{ toYaml . | indent 8 }} -{{- end }} - spec: - hostNetwork: true - dnsPolicy: {{ .Values.linux.dnsPolicy }} - serviceAccountName: {{ .Values.serviceAccount.node }} - nodeSelector: - kubernetes.io/os: linux -{{- with .Values.linux.nodeSelector }} -{{ toYaml . | indent 8 }} -{{- end }} - affinity: -{{- with .Values.linux.affinity }} -{{ toYaml . | indent 8 }} -{{- end }} - nodeAffinity: -{{ toYaml .Values.linux.nodeAffinity | indent 10 }} - priorityClassName: system-node-critical -{{- with .Values.linux.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} -{{- end }} - {{- if .Values.imagePullSecrets }} - imagePullSecrets: -{{ toYaml .Values.imagePullSecrets | indent 8 }} - {{- end }} - containers: - - name: liveness-probe - volumeMounts: - - mountPath: /csi - name: socket-dir -{{- if hasPrefix "/" .Values.image.livenessProbe.repository }} - image: "{{ .Values.image.baseRepo }}{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" -{{- else }} - image: "{{ .Values.image.livenessProbe.repository }}:{{ .Values.image.livenessProbe.tag }}" -{{- end }} - args: - - --csi-address=/csi/csi.sock - - --probe-timeout=3s - - --health-port={{ .Values.node.livenessProbe.healthPort }} - - --v=2 - imagePullPolicy: {{ .Values.image.livenessProbe.pullPolicy }} - resources: {{- toYaml .Values.linux.resources.livenessProbe | nindent 12 }} - - name: node-driver-registrar -{{- if hasPrefix "/" .Values.image.nodeDriverRegistrar.repository }} - image: "{{ .Values.image.baseRepo }}{{ .Values.image.nodeDriverRegistrar.repository }}:{{ .Values.image.nodeDriverRegistrar.tag }}" -{{- else }} - image: "{{ .Values.image.nodeDriverRegistrar.repository }}:{{ .Values.image.nodeDriverRegistrar.tag }}" -{{- end }} - args: - - --csi-address=$(ADDRESS) - - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) - - --v=2 - livenessProbe: - exec: - command: - - /csi-node-driver-registrar - - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) - - --mode=kubelet-registration-probe - initialDelaySeconds: 30 - timeoutSeconds: 15 - env: - - name: ADDRESS - value: /csi/csi.sock - - name: DRIVER_REG_SOCK_PATH - value: {{ .Values.linux.kubelet }}/plugins/{{ .Values.driver.name }}/csi.sock - imagePullPolicy: {{ .Values.image.nodeDriverRegistrar.pullPolicy }} - volumeMounts: - - name: socket-dir - mountPath: /csi - - name: registration-dir - mountPath: /registration - resources: {{- toYaml .Values.linux.resources.nodeDriverRegistrar | nindent 12 }} - - name: azurefile -{{- if hasPrefix "/" .Values.image.azurefile.repository }} - image: "{{ .Values.image.baseRepo }}{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" -{{- else }} - image: "{{ .Values.image.azurefile.repository }}:{{ .Values.image.azurefile.tag }}" -{{- end }} - args: - - "--v={{ .Values.node.logLevel }}" - - "--endpoint=$(CSI_ENDPOINT)" - - "--nodeid=$(KUBE_NODE_NAME)" - - "--metrics-address=0.0.0.0:{{ .Values.node.metricsPort }}" - - "--kubeconfig={{ .Values.linux.kubeconfig }}" - - "--drivername={{ .Values.driver.name }}" - - "--cloud-config-secret-name={{ .Values.node.cloudConfigSecretName }}" - - "--cloud-config-secret-namespace={{ .Values.node.cloudConfigSecretNamespace }}" - - "--custom-user-agent={{ .Values.driver.customUserAgent }}" - - "--user-agent-suffix={{ .Values.driver.userAgentSuffix }}" - - "--allow-empty-cloud-config={{ .Values.node.allowEmptyCloudConfig }}" - - "--enable-get-volume-stats={{ .Values.feature.enableGetVolumeStats }}" - - "--mount-permissions={{ .Values.linux.mountPermissions }}" - - "--allow-inline-volume-key-access-with-identity={{ .Values.node.allowInlineVolumeKeyAccessWithIdentity }}" - ports: - - containerPort: {{ .Values.node.livenessProbe.healthPort }} - name: healthz - protocol: TCP - livenessProbe: - failureThreshold: 5 - httpGet: - path: /healthz - port: healthz - initialDelaySeconds: 30 - timeoutSeconds: 10 - periodSeconds: 30 - env: - - name: AZURE_CREDENTIAL_FILE - valueFrom: - configMapKeyRef: - name: azure-cred-file - key: path - optional: true - - name: CSI_ENDPOINT - value: unix:///csi/csi.sock - {{- if ne .Values.driver.httpsProxy "" }} - - name: HTTPS_PROXY - value: {{ .Values.driver.httpsProxy }} - {{- end }} - {{- if ne .Values.driver.httpProxy "" }} - - name: HTTP_PROXY - value: {{ .Values.driver.httpProxy }} - {{- end }} - - name: KUBE_NODE_NAME - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: spec.nodeName - - name: AZURE_GO_SDK_LOG_LEVEL - value: {{ .Values.driver.azureGoSDKLogLevel }} - imagePullPolicy: {{ .Values.image.azurefile.pullPolicy }} - securityContext: - privileged: true - volumeMounts: - - mountPath: /csi - name: socket-dir - - mountPath: {{ .Values.linux.kubelet }}/ - mountPropagation: Bidirectional - name: mountpoint-dir - - mountPath: /etc/kubernetes/ - name: azure-cred - - mountPath: /dev - name: device-dir - {{- if eq .Values.linux.distro "fedora" }} - - name: ssl - mountPath: /etc/ssl/certs - readOnly: true - - name: ssl-pki - mountPath: /etc/pki/ca-trust/extracted - readOnly: true - {{- end }} - resources: {{- toYaml .Values.linux.resources.azurefile | nindent 12 }} - volumes: - - hostPath: - path: {{ .Values.linux.kubelet }}/plugins/{{ .Values.driver.name }} - type: DirectoryOrCreate - name: socket-dir - - hostPath: - path: {{ .Values.linux.kubelet }}/ - type: DirectoryOrCreate - name: mountpoint-dir - - hostPath: - path: {{ .Values.linux.kubelet }}/plugins_registry/ - type: DirectoryOrCreate - name: registration-dir - - hostPath: - path: /etc/kubernetes/ - type: DirectoryOrCreate - name: azure-cred - - hostPath: - path: /dev - type: Directory - name: device-dir - {{- if eq .Values.linux.distro "fedora" }} - - name: ssl - hostPath: - path: /etc/ssl/certs - - name: ssl-pki - hostPath: - path: /etc/pki/ca-trust/extracted - {{- end }} -{{- end -}} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/csi-snapshot-controller.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/csi-snapshot-controller.yaml deleted file mode 100644 index b1f7eff92c..0000000000 --- a/charts/v1.26.1/azurefile-csi-driver/templates/csi-snapshot-controller.yaml +++ /dev/null @@ -1,65 +0,0 @@ -{{- if .Values.snapshot.enabled -}} -kind: Deployment -apiVersion: apps/v1 -metadata: - name: {{ .Values.snapshot.snapshotController.name}} - namespace: {{ .Release.Namespace }} - labels: - app: {{ .Values.snapshot.snapshotController.name}} - {{- include "azurefile.labels" . | nindent 4 }} -{{- with .Values.snapshot.snapshotController.labels }} -{{ . | toYaml | indent 4 }} -{{- end }} -{{- with .Values.snapshot.snapshotController.annotations }} - annotations: -{{ . | toYaml | indent 4 }} -{{- end }} -spec: - replicas: {{ .Values.snapshot.snapshotController.replicas }} - selector: - matchLabels: - app: {{ .Values.snapshot.snapshotController.name}} - {{- include "azurefile.selectorLabels" . | nindent 6 }} - template: - metadata: - labels: - app: {{ .Values.snapshot.snapshotController.name}} - {{- include "azurefile.labels" . | nindent 8 }} -{{- with .Values.snapshot.snapshotController.podLabels }} -{{ toYaml . | indent 8 }} -{{- end }} -{{- with .Values.snapshot.snapshotController.podAnnotations }} - annotations: -{{ toYaml . | indent 8 }} -{{- end }} - spec: - serviceAccountName: {{ .Values.serviceAccount.snapshotController }} - nodeSelector: - kubernetes.io/os: linux - priorityClassName: system-cluster-critical -{{- with .Values.controller.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} -{{- end }} -{{- with .Values.controller.affinity }} - affinity: -{{ toYaml . | indent 8 }} -{{- end }} - {{- if .Values.imagePullSecrets }} - imagePullSecrets: -{{ toYaml .Values.imagePullSecrets | indent 8 }} - {{- end }} - containers: - - name: {{ .Values.snapshot.snapshotController.name}} -{{- if hasPrefix "/" .Values.snapshot.image.csiSnapshotController.repository }} - image: "{{ .Values.image.baseRepo }}{{ .Values.snapshot.image.csiSnapshotController.repository }}:{{ .Values.snapshot.image.csiSnapshotController.tag }}" -{{- else }} - image: "{{ .Values.snapshot.image.csiSnapshotController.repository }}:{{ .Values.snapshot.image.csiSnapshotController.tag }}" -{{- end }} - args: - - "--v=2" - - "--leader-election=true" - - "--leader-election-namespace={{ .Release.Namespace }}" - resources: {{- toYaml .Values.snapshot.snapshotController.resources | nindent 12 }} - imagePullPolicy: {{ .Values.snapshot.image.csiSnapshotController.pullPolicy }} -{{- end -}} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml deleted file mode 100644 index 09923c06a5..0000000000 --- a/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-controller.yaml +++ /dev/null @@ -1,207 +0,0 @@ -{{- if .Values.rbac.create -}} -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ .Values.rbac.name }}-external-provisioner-role - labels: - {{- include "azurefile.labels" . | nindent 4 }} -rules: - - 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: ["get", "list", "watch", "create", "update", "patch"] - - apiGroups: ["storage.k8s.io"] - resources: ["csinodes"] - verbs: ["get", "list", "watch"] - - apiGroups: [""] - resources: ["nodes"] - verbs: ["get", "list", "watch"] - - apiGroups: ["snapshot.storage.k8s.io"] - resources: ["volumesnapshots"] - verbs: ["get", "list"] - - apiGroups: ["snapshot.storage.k8s.io"] - resources: ["volumesnapshotcontents"] - verbs: ["get", "list"] - - apiGroups: ["coordination.k8s.io"] - resources: ["leases"] - verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] ---- - -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ .Values.rbac.name }}-csi-provisioner-binding - labels: - {{- include "azurefile.labels" . | nindent 4 }} -subjects: - - kind: ServiceAccount - name: {{ .Values.serviceAccount.controller }} - namespace: {{ .Release.Namespace }} -roleRef: - kind: ClusterRole - name: {{ .Values.rbac.name }}-external-provisioner-role - apiGroup: rbac.authorization.k8s.io - ---- - -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ .Values.rbac.name }}-external-attacher-role - labels: - {{- include "azurefile.labels" . | nindent 4 }} -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", "patch"] - - apiGroups: ["storage.k8s.io"] - resources: ["volumeattachments/status"] - verbs: ["get", "list", "watch", "update", "patch"] - - apiGroups: ["coordination.k8s.io"] - resources: ["leases"] - verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] ---- - -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ .Values.rbac.name }}-csi-attacher-binding - labels: - {{- include "azurefile.labels" . | nindent 4 }} -subjects: - - kind: ServiceAccount - name: {{ .Values.serviceAccount.controller }} - namespace: {{ .Release.Namespace }} -roleRef: - kind: ClusterRole - name: {{ .Values.rbac.name }}-external-attacher-role - apiGroup: rbac.authorization.k8s.io - ---- - -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ .Values.rbac.name }}-external-snapshotter-role - labels: - {{- include "azurefile.labels" . | nindent 4 }} -rules: - - apiGroups: [""] - resources: ["events"] - verbs: ["list", "watch", "create", "update", "patch"] - - apiGroups: [""] - resources: ["secrets"] - verbs: ["get"] - - apiGroups: ["snapshot.storage.k8s.io"] - resources: ["volumesnapshotclasses"] - verbs: ["get", "list", "watch"] - - apiGroups: ["snapshot.storage.k8s.io"] - resources: ["volumesnapshotcontents"] - verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] - - apiGroups: ["snapshot.storage.k8s.io"] - resources: ["volumesnapshotcontents/status"] - verbs: ["update", "patch"] - - apiGroups: ["coordination.k8s.io"] - resources: ["leases"] - verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] ---- - -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ .Values.rbac.name }}-csi-snapshotter-binding - labels: - {{- include "azurefile.labels" . | nindent 4 }} -subjects: - - kind: ServiceAccount - name: {{ .Values.serviceAccount.controller }} - namespace: {{ .Release.Namespace }} -roleRef: - kind: ClusterRole - name: {{ .Values.rbac.name }}-external-snapshotter-role - apiGroup: rbac.authorization.k8s.io - ---- -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ .Values.rbac.name }}-external-resizer-role - labels: - {{- include "azurefile.labels" . | nindent 4 }} -rules: - - apiGroups: [""] - resources: ["persistentvolumes"] - verbs: ["get", "list", "watch", "update", "patch"] - - apiGroups: [""] - resources: ["persistentvolumeclaims"] - verbs: ["get", "list", "watch"] - - apiGroups: [""] - resources: ["persistentvolumeclaims/status"] - verbs: ["update", "patch"] - - apiGroups: [""] - resources: ["events"] - verbs: ["list", "watch", "create", "update", "patch"] - - apiGroups: ["coordination.k8s.io"] - resources: ["leases"] - verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ .Values.rbac.name }}-csi-resizer-role - labels: - {{- include "azurefile.labels" . | nindent 4 }} -subjects: - - kind: ServiceAccount - name: {{ .Values.serviceAccount.controller }} - namespace: {{ .Release.Namespace }} -roleRef: - kind: ClusterRole - name: {{ .Values.rbac.name }}-external-resizer-role - apiGroup: rbac.authorization.k8s.io - ---- -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: csi-{{ .Values.rbac.name }}-controller-secret-role - labels: - {{- include "azurefile.labels" . | nindent 4 }} -rules: - - apiGroups: [""] - resources: ["secrets"] - verbs: ["get", "create"] - ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: csi-{{ .Values.rbac.name }}-controller-secret-binding - labels: - {{- include "azurefile.labels" . | nindent 4 }} -subjects: - - kind: ServiceAccount - name: {{ .Values.serviceAccount.controller }} - namespace: {{ .Release.Namespace }} -roleRef: - kind: ClusterRole - name: csi-{{ .Values.rbac.name }}-controller-secret-role - apiGroup: rbac.authorization.k8s.io -{{ end }} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml deleted file mode 100644 index 4e1fbcde94..0000000000 --- a/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-azurefile-node.yaml +++ /dev/null @@ -1,29 +0,0 @@ -{{- if .Values.rbac.create -}} ---- -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: csi-{{ .Values.rbac.name }}-node-secret-role - labels: - {{- include "azurefile.labels" . | nindent 4 }} -rules: - - apiGroups: [""] - resources: ["secrets"] - verbs: ["get"] - ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: csi-{{ .Values.rbac.name }}-node-secret-binding - labels: - {{- include "azurefile.labels" . | nindent 4 }} -subjects: - - kind: ServiceAccount - name: {{ .Values.serviceAccount.node }} - namespace: {{ .Release.Namespace }} -roleRef: - kind: ClusterRole - name: csi-{{ .Values.rbac.name }}-node-secret-role - apiGroup: rbac.authorization.k8s.io -{{ end }} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml deleted file mode 100644 index 0cff1ff01f..0000000000 --- a/charts/v1.26.1/azurefile-csi-driver/templates/rbac-csi-snapshot-controller.yaml +++ /dev/null @@ -1,80 +0,0 @@ -{{- if and .Values.snapshot.enabled .Values.rbac.create -}} -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: csi-snapshot-controller-role - labels: - {{- include "azurefile.labels" . | nindent 4 }} -rules: - - apiGroups: [""] - resources: ["persistentvolumes"] - verbs: ["get", "list", "watch"] - - 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: ["volumesnapshotclasses"] - verbs: ["get", "list", "watch"] - - apiGroups: ["snapshot.storage.k8s.io"] - resources: ["volumesnapshotcontents"] - verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] - - apiGroups: ["snapshot.storage.k8s.io"] - resources: ["volumesnapshotcontents/status"] - verbs: ["patch"] - - apiGroups: ["snapshot.storage.k8s.io"] - resources: ["volumesnapshots"] - verbs: ["get", "list", "watch", "update", "patch"] - - apiGroups: ["snapshot.storage.k8s.io"] - resources: ["volumesnapshots/status"] - verbs: ["update", "patch"] - ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: csi-snapshot-controller-binding - labels: - {{- include "azurefile.labels" . | nindent 4 }} -subjects: - - kind: ServiceAccount - name: {{ .Values.serviceAccount.snapshotController }} - namespace: {{ .Release.Namespace }} -roleRef: - kind: ClusterRole - name: csi-snapshot-controller-role - apiGroup: rbac.authorization.k8s.io - ---- -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: csi-snapshot-controller-leaderelection-role - labels: - {{- include "azurefile.labels" . | nindent 4 }} -rules: - - apiGroups: ["coordination.k8s.io"] - resources: ["leases"] - verbs: ["get", "watch", "list", "delete", "update", "create", "patch"] - ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: csi-snapshot-controller-leaderelection-binding - labels: - {{- include "azurefile.labels" . | nindent 4 }} -subjects: - - kind: ServiceAccount - name: {{ .Values.serviceAccount.snapshotController }} - namespace: {{ .Release.Namespace }} -roleRef: - kind: ClusterRole - name: csi-snapshot-controller-leaderelection-role - apiGroup: rbac.authorization.k8s.io -{{ end }} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml deleted file mode 100644 index 66e0726acb..0000000000 --- a/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-controller.yaml +++ /dev/null @@ -1,9 +0,0 @@ -{{- if .Values.serviceAccount.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ .Values.serviceAccount.controller }} - namespace: {{ .Release.Namespace }} - labels: - {{- include "azurefile.labels" . | nindent 4 }} -{{- end -}} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml deleted file mode 100644 index 697b8db390..0000000000 --- a/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-azurefile-node.yaml +++ /dev/null @@ -1,9 +0,0 @@ -{{- if .Values.serviceAccount.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ .Values.serviceAccount.node }} - namespace: {{ .Release.Namespace }} - labels: - {{- include "azurefile.labels" . | nindent 4 }} -{{- end -}} diff --git a/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml b/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml deleted file mode 100644 index e77ef8f991..0000000000 --- a/charts/v1.26.1/azurefile-csi-driver/templates/serviceaccount-csi-snapshot-controller.yaml +++ /dev/null @@ -1,9 +0,0 @@ -{{- if and .Values.snapshot.enabled .Values.serviceAccount.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ .Values.serviceAccount.snapshotController }} - namespace: {{ .Release.Namespace }} - labels: - {{- include "azurefile.labels" . | nindent 4 }} -{{- end -}} diff --git a/charts/v1.26.2/azurefile-csi-driver-v1.26.2.tgz b/charts/v1.26.2/azurefile-csi-driver-v1.26.2.tgz deleted file mode 100644 index ecf496d2c0e3b6debc62aeea9839171d01c7b343..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11417 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 Date: Sun, 21 May 2023 01:57:41 +0000 Subject: [PATCH 101/109] chore: refactor host process code fix --- .../safe_mounter_host_process_windows.go | 46 +----- pkg/os/filesystem/filesystem.go | 100 +++--------- pkg/os/filesystem/types.go | 143 ------------------ 3 files changed, 28 insertions(+), 261 deletions(-) delete mode 100644 pkg/os/filesystem/types.go diff --git a/pkg/mounter/safe_mounter_host_process_windows.go b/pkg/mounter/safe_mounter_host_process_windows.go index bacb57baaa..9286626cfb 100644 --- a/pkg/mounter/safe_mounter_host_process_windows.go +++ b/pkg/mounter/safe_mounter_host_process_windows.go @@ -131,31 +131,13 @@ func (mounter *winMounter) SMBUnmount(target string) error { } // Mount just creates a soft link at target pointing to source. -func (mounter *winMounter) Mount(source string, target string, fstype string, options []string) error { - klog.V(4).Infof("Mount: old name: %s. new name: %s", source, target) - // Mount is called after the format is done. - // TODO: Confirm that fstype is empty. - linkRequest := &filesystem.LinkPathRequest{ - SourcePath: normalizeWindowsPath(source), - TargetPath: normalizeWindowsPath(target), - } - if err := filesystem.LinkPath(context.Background(), linkRequest); err != nil { - return err - } - return nil +func (mounter *winMounter) Mount(source, target, fstype string, options []string) error { + return filesystem.LinkPath(normalizeWindowsPath(source), normalizeWindowsPath(target)) } // Rmdir - delete the given directory func (mounter *winMounter) Rmdir(path string) error { - klog.V(4).Infof("Remove directory: %s", path) - rmdirRequest := &filesystem.RmdirRequest{ - Path: normalizeWindowsPath(path), - Force: true, - } - if err := filesystem.Rmdir(context.Background(), rmdirRequest); err != nil { - return err - } - return nil + return filesystem.Rmdir(normalizeWindowsPath(path), true) } // Unmount - Removes the directory - equivalent to unmount on Linux. @@ -183,7 +165,6 @@ func (mounter *winMounter) IsMountPointMatch(mp mount.MountPoint, dir string) bo // IsLikelyMountPoint - If the directory does not exists, the function will return os.ErrNotExist error. // If the path exists, will check if its a link, if its a link then existence of target path is checked. func (mounter *winMounter) IsLikelyNotMountPoint(path string) (bool, error) { - klog.V(4).Infof("IsLikelyNotMountPoint: %s", path) isExists, err := mounter.ExistsPath(path) if err != nil { return false, err @@ -192,10 +173,7 @@ func (mounter *winMounter) IsLikelyNotMountPoint(path string) (bool, error) { return true, os.ErrNotExist } - response, err := filesystem.IsMountPoint(context.Background(), - &filesystem.IsMountPointRequest{ - Path: normalizeWindowsPath(path), - }) + response, err := filesystem.IsMountPoint(normalizeWindowsPath(path)) if err != nil { return false, err } @@ -206,24 +184,12 @@ func (mounter *winMounter) IsLikelyNotMountPoint(path string) (bool, error) { // Currently the make dir is only used from the staging code path, hence we call it // with Plugin context.. func (mounter *winMounter) MakeDir(path string) error { - klog.V(4).Infof("Make directory: %s", path) - mkdirReq := &filesystem.MkdirRequest{ - Path: normalizeWindowsPath(path), - } - if err := filesystem.Mkdir(context.Background(), mkdirReq); err != nil { - return err - } - - return nil + return filesystem.Mkdir(normalizeWindowsPath(path)) } // ExistsPath - Checks if a path exists. Unlike util ExistsPath, this call does not perform follow link. func (mounter *winMounter) ExistsPath(path string) (bool, error) { - klog.V(4).Infof("Exists path: %s", path) - return filesystem.PathExists(context.Background(), - &filesystem.PathExistsRequest{ - Path: normalizeWindowsPath(path), - }) + return filesystem.PathExists(normalizeWindowsPath(path)) } func (mounter *winMounter) MountSensitive(source string, target string, fstype string, options []string, sensitiveOptions []string) error { diff --git a/pkg/os/filesystem/filesystem.go b/pkg/os/filesystem/filesystem.go index d2cf1ee2d9..6b4f972ed6 100644 --- a/pkg/os/filesystem/filesystem.go +++ b/pkg/os/filesystem/filesystem.go @@ -72,18 +72,12 @@ func pathExists(path string) (bool, error) { } // PathExists checks if the given path exists on the host. -func PathExists(ctx context.Context, request *PathExistsRequest) (bool, error) { - klog.V(2).Infof("Request: PathExists with path=%q", request.Path) - err := ValidatePathWindows(request.Path) - if err != nil { +func PathExists(path string) (bool, error) { + if err := ValidatePathWindows(path); err != nil { klog.Errorf("failed validatePathWindows %v", err) return false, err } - exists, err := pathExists(request.Path) - if err != nil { - klog.Errorf("failed check PathExists %v", err) - } - return exists, err + return pathExists(path) } func PathValid(ctx context.Context, path string) (bool, error) { @@ -129,94 +123,44 @@ func ValidatePathWindows(path string) error { return nil } -func Mkdir(ctx context.Context, request *MkdirRequest) error { - klog.V(2).Infof("Request: Mkdir with path=%q", request.Path) - err := ValidatePathWindows(request.Path) - if err != nil { - klog.Errorf("failed validatePathWindows %v", err) - return err - } - err = os.MkdirAll(request.Path, 0755) - if err != nil { - klog.Errorf("failed Mkdir %v", err) +func Mkdir(path string) error { + if err := ValidatePathWindows(path); err != nil { return err } - - return err + return os.MkdirAll(path, 0755) } -func Rmdir(ctx context.Context, request *RmdirRequest) error { - klog.V(2).Infof("Request: Rmdir with path=%q", request.Path) - err := ValidatePathWindows(request.Path) - if err != nil { - klog.Errorf("failed validatePathWindows %v", err) +func Rmdir(path string, force bool) error { + if err := ValidatePathWindows(path); err != nil { return err } - if request.Force { - err = os.RemoveAll(request.Path) - } else { - err = os.Remove(request.Path) + if force { + return os.RemoveAll(path) } - if err != nil { - klog.Errorf("failed Rmdir %v", err) - return err - } - - return err + return os.Remove(path) } -func LinkPath(ctx context.Context, request *LinkPathRequest) error { - klog.V(2).Infof("Request: LinkPath with targetPath=%q sourcePath=%q", request.TargetPath, request.SourcePath) - createSymlinkRequest := &CreateSymlinkRequest{ - SourcePath: request.SourcePath, - TargetPath: request.TargetPath, - } - if err := CreateSymlink(ctx, createSymlinkRequest); err != nil { - klog.Errorf("Failed to forward to CreateSymlink: %v", err) - return err - } - return nil + +func LinkPath(sourcePath, targetPath string) error { + return CreateSymlink(sourcePath, targetPath) } -func CreateSymlink(ctx context.Context, request *CreateSymlinkRequest) error { - klog.V(2).Infof("Request: CreateSymlink with targetPath=%q sourcePath=%q", request.TargetPath, request.SourcePath) - err := ValidatePathWindows(request.TargetPath) - if err != nil { - klog.Errorf("failed validatePathWindows for target path %v", err) +func CreateSymlink(sourcePath, targetPath string) error { + if err := ValidatePathWindows(targetPath); err != nil { return err } - err = ValidatePathWindows(request.SourcePath) - if err != nil { - klog.Errorf("failed validatePathWindows for source path %v", err) + if err := ValidatePathWindows(sourcePath); err != nil { return err } - err = os.Symlink(request.SourcePath, request.TargetPath) - if err != nil { - klog.Errorf("failed CreateSymlink: %v", err) - return err - } - return nil + return os.Symlink(sourcePath, targetPath) } -func IsMountPoint(ctx context.Context, request *IsMountPointRequest) (bool, error) { - klog.V(2).Infof("Request: IsMountPoint with path=%q", request.Path) - isSymlinkRequest := &IsSymlinkRequest{ - Path: request.Path, - } - isSymlink, err := IsSymlink(ctx, isSymlinkRequest) - if err != nil { - klog.Errorf("Failed to forward to IsSymlink: %v", err) - } - return isSymlink, err +func IsMountPoint(path string) (bool, error) { + return IsSymlink(path) } -func IsSymlink(ctx context.Context, request *IsSymlinkRequest) (bool, error) { - klog.V(2).Infof("Request: IsSymlink with path=%q", request.Path) - isSymlink, err := isSymlink(request.Path) - if err != nil { - klog.Errorf("failed IsSymlink %v", err) - } - return isSymlink, err +func IsSymlink(path string) (bool, error) { + return isSymlink(path) } // IsSymlink - returns true if tgt is a mount point. diff --git a/pkg/os/filesystem/types.go b/pkg/os/filesystem/types.go deleted file mode 100644 index 208fe50f25..0000000000 --- a/pkg/os/filesystem/types.go +++ /dev/null @@ -1,143 +0,0 @@ -/* -Copyright 2023 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 filesystem - -type PathExistsRequest struct { - // The path whose existence we want to check in the host's filesystem - Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` -} - -type MkdirRequest struct { - // The path to create in the host's filesystem. - // All special characters allowed by Windows in path names will be allowed - // except for restrictions noted below. For details, please check: - // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file - // Non-existent parent directories in the path will be automatically created. - // Directories will be created with Read and Write privileges of the Windows - // User account under which csi-proxy is started (typically LocalSystem). - // - // Restrictions: - // Only absolute path (indicated by a drive letter prefix: e.g. "C:\") is accepted. - // Depending on the context parameter of this function, the path prefix needs - // to match the paths specified either as kubelet-csi-plugins-path - // or as kubelet-pod-path parameters of csi-proxy. - // The path parameter cannot already exist in the host's filesystem. - // UNC paths of the form "\\server\share\path\file" are not allowed. - // All directory separators need to be backslash character: "\". - // Characters: .. / : | ? * in the path are not allowed. - // Maximum path length will be capped to 260 characters. - Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` -} - -type RmdirRequest struct { - // The path to remove in the host's filesystem. - // All special characters allowed by Windows in path names will be allowed - // except for restrictions noted below. For details, please check: - // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file - // - // Restrictions: - // Only absolute path (indicated by a drive letter prefix: e.g. "C:\") is accepted. - // Depending on the context parameter of this function, the path prefix needs - // to match the paths specified either as kubelet-csi-plugins-path - // or as kubelet-pod-path parameters of csi-proxy. - // UNC paths of the form "\\server\share\path\file" are not allowed. - // All directory separators need to be backslash character: "\". - // Characters: .. / : | ? * in the path are not allowed. - // Path cannot be a file of type symlink. - // Maximum path length will be capped to 260 characters. - Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` - // Force remove all contents under path (if any). - Force bool `protobuf:"varint,2,opt,name=force,proto3" json:"force,omitempty"` -} - -type LinkPathRequest struct { - // The path where the symlink is created in the host's filesystem. - // All special characters allowed by Windows in path names will be allowed - // except for restrictions noted below. For details, please check: - // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file - // - // Restrictions: - // Only absolute path (indicated by a drive letter prefix: e.g. "C:\") is accepted. - // The path prefix needs to match the paths specified as - // kubelet-csi-plugins-path parameter of csi-proxy. - // UNC paths of the form "\\server\share\path\file" are not allowed. - // All directory separators need to be backslash character: "\". - // Characters: .. / : | ? * in the path are not allowed. - // source_path cannot already exist in the host filesystem. - // Maximum path length will be capped to 260 characters. - SourcePath string `protobuf:"bytes,1,opt,name=source_path,json=sourcePath,proto3" json:"source_path,omitempty"` - // Target path in the host's filesystem used for the symlink creation. - // All special characters allowed by Windows in path names will be allowed - // except for restrictions noted below. For details, please check: - // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file - // - // Restrictions: - // Only absolute path (indicated by a drive letter prefix: e.g. "C:\") is accepted. - // The path prefix needs to match the paths specified as - // kubelet-pod-path parameter of csi-proxy. - // UNC paths of the form "\\server\share\path\file" are not allowed. - // All directory separators need to be backslash character: "\". - // Characters: .. / : | ? * in the path are not allowed. - // target_path needs to exist as a directory in the host that is empty. - // target_path cannot be a symbolic link. - // Maximum path length will be capped to 260 characters. - TargetPath string `protobuf:"bytes,2,opt,name=target_path,json=targetPath,proto3" json:"target_path,omitempty"` -} - -type CreateSymlinkRequest struct { - // The path of the existing directory to be linked. - // All special characters allowed by Windows in path names will be allowed - // except for restrictions noted below. For details, please check: - // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file - // - // Restrictions: - // Only absolute path (indicated by a drive letter prefix: e.g. "C:\") is accepted. - // The path prefix needs needs to match the paths specified as - // kubelet-csi-plugins-path parameter of csi-proxy. - // UNC paths of the form "\\server\share\path\file" are not allowed. - // All directory separators need to be backslash character: "\". - // Characters: .. / : | ? * in the path are not allowed. - // source_path cannot already exist in the host filesystem. - // Maximum path length will be capped to 260 characters. - SourcePath string `protobuf:"bytes,1,opt,name=source_path,json=sourcePath,proto3" json:"source_path,omitempty"` - // Target path is the location of the new directory entry to be created in the host's filesystem. - // All special characters allowed by Windows in path names will be allowed - // except for restrictions noted below. For details, please check: - // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file - // - // Restrictions: - // Only absolute path (indicated by a drive letter prefix: e.g. "C:\") is accepted. - // The path prefix needs to match the paths specified as - // kubelet-pod-path parameter of csi-proxy. - // UNC paths of the form "\\server\share\path\file" are not allowed. - // All directory separators need to be backslash character: "\". - // Characters: .. / : | ? * in the path are not allowed. - // target_path needs to exist as a directory in the host that is empty. - // target_path cannot be a symbolic link. - // Maximum path length will be capped to 260 characters. - TargetPath string `protobuf:"bytes,2,opt,name=target_path,json=targetPath,proto3" json:"target_path,omitempty"` -} - -type IsMountPointRequest struct { - // The path whose existence we want to check in the host's filesystem - Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` -} - -type IsSymlinkRequest struct { - // The path whose existence as a symlink we want to check in the host's filesystem. - Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` -} From b994a208cf5d77bace342ba70acd8a2341b6c03f Mon Sep 17 00:00:00 2001 From: andyzhangx Date: Sun, 21 May 2023 08:40:52 +0000 Subject: [PATCH 102/109] chore: rename helm chart value as windows.useHostProcessContainers refine --- Makefile | 27 ++++-------------- charts/README.md | 2 +- charts/latest/azurefile-csi-driver-v0.0.0.tgz | Bin 13266 -> 13275 bytes ...si-azurefile-node-windows-hostprocess.yaml | 2 +- .../templates/csi-azurefile-node-windows.yaml | 2 +- .../latest/azurefile-csi-driver/values.yaml | 2 +- 6 files changed, 10 insertions(+), 25 deletions(-) diff --git a/Makefile b/Makefile index a04a815c6a..d606988a6e 100755 --- a/Makefile +++ b/Makefile @@ -59,6 +59,8 @@ ARCH ?= amd64 OSVERSION ?= 1809 # Output type of docker buildx build OUTPUT_TYPE ?= registry +# enable host process containers for Windows +USE_HOST_PROCESS_CONTAINERS ?= false .EXPORT_ALL_VARIABLES: @@ -95,45 +97,28 @@ e2e-test: go test -v -timeout=0 ./test/e2e ${GINKGO_FLAGS};\ fi -# In the scenario "host-process" and "csi-proxy", use the same daemonset name. -# The command "helm install" would validate if the name is duplicated and return error or not. -# So here we have to use flag "--disable-openapi-validation" to skip the validation. .PHONY: e2e-bootstrap e2e-bootstrap: install-helm ifdef WINDOWS_USE_HOST_PROCESS_CONTAINERS (docker pull $(CSI_IMAGE_TAG) && docker pull $(CSI_IMAGE_TAG)-windows-hp) || make container-all push-manifest + USE_HOST_PROCESS_CONTAINERS=${WINDOWS_USE_HOST_PROCESS_CONTAINERS} else docker pull $(CSI_IMAGE_TAG) || make container-all push-manifest endif ifdef TEST_WINDOWS -ifdef WINDOWS_USE_HOST_PROCESS_CONTAINERS - helm install azurefile-csi-driver charts/latest/azurefile-csi-driver --namespace kube-system --wait --timeout=15m -v=5 --debug \ - ${E2E_HELM_OPTIONS} \ - --set windows.enabled=true \ - --set windows.hostprocess=true \ - --set linux.enabled=false \ - --set driver.azureGoSDKLogLevel=INFO \ - --set controller.replicas=1 \ - --set controller.logLevel=6 \ - --set node.logLevel=6 \ - --disable-openapi-validation -else helm install azurefile-csi-driver charts/latest/azurefile-csi-driver --namespace kube-system --wait --timeout=15m -v=5 --debug \ ${E2E_HELM_OPTIONS} \ --set windows.enabled=true \ - --set windows.hostprocess=false \ + --set windows.useHostProcessContainers=${USE_HOST_PROCESS_CONTAINERS} \ --set linux.enabled=false \ --set driver.azureGoSDKLogLevel=INFO \ --set controller.replicas=1 \ --set controller.logLevel=6 \ - --set node.logLevel=6 \ - --disable-openapi-validation -endif + --set node.logLevel=6 else helm install azurefile-csi-driver charts/latest/azurefile-csi-driver --namespace kube-system --wait --timeout=15m -v=5 --debug \ ${E2E_HELM_OPTIONS} \ - --set snapshot.enabled=true \ - --disable-openapi-validation + --set snapshot.enabled=true endif .PHONY: install-helm diff --git a/charts/README.md b/charts/README.md index 0fb465b615..6f7a3eb6cb 100644 --- a/charts/README.md +++ b/charts/README.md @@ -168,7 +168,7 @@ The following table lists the configurable parameters of the latest Azure File C | `linux.resources.azurefile.requests.memory` | azurefile memory requests | 20Mi | | `windows.enabled` | whether enable windows feature | `true` | | `windows.dsName` | name of driver daemonset on windows |`csi-azurefile-node-win` | -| `windows.hostprocess` | whether deploy driver daemonset with host process containers on windows | `false` | +| `windows.useHostProcessContainers` | whether deploy driver daemonset with host process containers on windows | `false` | | `windows.kubelet` | configure kubelet directory path on Windows agent node | `'C:\var\lib\kubelet'` | | `windows.kubeconfig` | configure kubeconfig path on Windows agent node | `'C:\k\config'` | | `windows.enableRegistrationProbe` | enable [kubelet-registration-probe](https://github.com/kubernetes-csi/node-driver-registrar#health-check-with-an-exec-probe) on windows driver config | `true` diff --git a/charts/latest/azurefile-csi-driver-v0.0.0.tgz b/charts/latest/azurefile-csi-driver-v0.0.0.tgz index c44b3c3ab9d0e18fa8d27ab188754fa49213a28c..75517a4ddd93e4200ce3b5d14a79b83d0e31cf08 100644 GIT binary patch delta 12084 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 v#2@DHieWCfdXY&{LH#PL;I)4dF+=N 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