Merge pull request #29 from ceph/devel

syncing devel branch to get latest  updates
This commit is contained in:
OpenShift Merge Robot 2021-09-07 12:11:39 +02:00 committed by GitHub
commit 4cc0d868ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
264 changed files with 15197 additions and 8379 deletions

View File

@ -8,6 +8,7 @@ on:
jobs: jobs:
commitlint: commitlint:
name: commitlint name: commitlint
if: ${{ github.actor != 'dependabot[bot]' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2

View File

@ -26,6 +26,7 @@ pull_request_rules:
- name: ask to resolve conflict - name: ask to resolve conflict
conditions: conditions:
- conflict - conflict
- author!=dependabot[bot]
actions: actions:
comment: comment:
# yamllint disable-line rule:truthy # yamllint disable-line rule:truthy

View File

@ -8,7 +8,7 @@ Card](https://goreportcard.com/badge/github.com/ceph/ceph-csi)](https://goreport
- [Ceph CSI](#ceph-csi) - [Ceph CSI](#ceph-csi)
- [Overview](#overview) - [Overview](#overview)
- [Project status](#project-status) - [Project status](#project-status)
- [Supported CO platforms](#supported-co-platforms) - [Known to work CO platforms](#known-to-work-co-platforms)
- [Support Matrix](#support-matrix) - [Support Matrix](#support-matrix)
- [Ceph-CSI features and available versions](#ceph-csi-features-and-available-versions) - [Ceph-CSI features and available versions](#ceph-csi-features-and-available-versions)
- [CSI spec and Kubernetes version compatibility](#csi-spec-and-kubernetes-version-compatibility) - [CSI spec and Kubernetes version compatibility](#csi-spec-and-kubernetes-version-compatibility)
@ -47,11 +47,18 @@ NOTE:
Status: **GA** Status: **GA**
## Supported CO platforms ## Known to work CO platforms
Ceph CSI drivers are currently developed and tested **exclusively** on Kubernetes Ceph CSI drivers are currently developed and tested **exclusively** on Kubernetes
environments. There is work in progress to make this CO independent and thus environments.
support other orchestration environments in the future.
| Ceph CSI Version | Container Orchestrator Name | Version Tested|
| -----------------| --------------------------- | --------------|
| v3.4.0 | Kubernetes | v1.20, v1.21, v1.22|
| v3.3.0 | Kubernetes | v1.20, v1.21, v1.22|
There is work in progress to make this CO independent and thus
support other orchestration environments (Nomad, Mesos..etc) in the future.
NOTE: NOTE:

View File

@ -39,7 +39,7 @@ SNAPSHOT_VERSION=v4.0.0
HELM_VERSION=v3.1.2 HELM_VERSION=v3.1.2
# minikube settings # minikube settings
MINIKUBE_VERSION=v1.22.0 MINIKUBE_VERSION=v1.23.0
VM_DRIVER=none VM_DRIVER=none
CHANGE_MINIKUBE_NONE_USER=true CHANGE_MINIKUBE_NONE_USER=true

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: ceph-config
namespace: {{ .Release.Namespace }}
labels:
app: {{ include "ceph-csi-cephfs.name" . }}
chart: {{ include "ceph-csi-cephfs.chart" . }}
component: {{ .Values.nodeplugin.name }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
data:
ceph.conf: |
{{ tpl .Values.cephconf . | indent 4 }}
keyring: ""

View File

@ -118,6 +118,8 @@ spec:
- mountPath: /lib/modules - mountPath: /lib/modules
name: lib-modules name: lib-modules
readOnly: true readOnly: true
- name: ceph-config
mountPath: /etc/ceph/
- name: ceph-csi-config - name: ceph-csi-config
mountPath: /etc/ceph-csi-config/ mountPath: /etc/ceph-csi-config/
- name: keys-tmp-dir - name: keys-tmp-dir
@ -182,6 +184,9 @@ spec:
- name: host-dev - name: host-dev
hostPath: hostPath:
path: /dev path: /dev
- name: ceph-config
configMap:
name: ceph-config
- name: ceph-csi-config - name: ceph-csi-config
configMap: configMap:
name: {{ .Values.configMapName | quote }} name: {{ .Values.configMapName | quote }}

View File

@ -173,6 +173,8 @@ spec:
readOnly: true readOnly: true
- name: host-dev - name: host-dev
mountPath: /dev mountPath: /dev
- name: ceph-config
mountPath: /etc/ceph/
- name: ceph-csi-config - name: ceph-csi-config
mountPath: /etc/ceph-csi-config/ mountPath: /etc/ceph-csi-config/
- name: keys-tmp-dir - name: keys-tmp-dir
@ -217,6 +219,9 @@ spec:
- name: host-dev - name: host-dev
hostPath: hostPath:
path: /dev path: /dev
- name: ceph-config
configMap:
name: ceph-config
- name: ceph-csi-config - name: ceph-csi-config
configMap: configMap:
name: {{ .Values.configMapName | quote }} name: {{ .Values.configMapName | quote }}

View File

@ -275,6 +275,26 @@ secret:
adminID: <plaintext ID> adminID: <plaintext ID>
adminKey: <Ceph auth key corresponding to ID above> adminKey: <Ceph auth key corresponding to ID above>
# This is a sample configmap that helps define a Ceph configuration as required
# by the CSI plugins.
# Sample ceph.conf available at
# https://github.com/ceph/ceph/blob/master/src/sample.ceph.conf Detailed
# documentation is available at
# https://docs.ceph.com/en/latest/rados/configuration/ceph-conf/
cephconf: |
[global]
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
# Workaround for http://tracker.ceph.com/issues/23446
fuse_set_user_groups = false
# ceph-fuse which uses libfuse2 by default has write buffer size of 2KiB
# adding 'fuse_big_writes = true' option by default to override this limit
# see https://github.com/ceph/ceph-csi/issues/1928
fuse_big_writes = true
######################################################### #########################################################
# Variables for 'internal' use please use with caution! # # Variables for 'internal' use please use with caution! #
######################################################### #########################################################

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: ceph-config
namespace: {{ .Release.Namespace }}
labels:
app: {{ include "ceph-csi-rbd.name" . }}
chart: {{ include "ceph-csi-rbd.chart" . }}
component: {{ .Values.nodeplugin.name }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
data:
ceph.conf: |
{{ tpl .Values.cephconf . | indent 4 }}
keyring: ""

View File

@ -114,6 +114,8 @@ spec:
readOnly: true readOnly: true
- name: ceph-csi-config - name: ceph-csi-config
mountPath: /etc/ceph-csi-config/ mountPath: /etc/ceph-csi-config/
- name: ceph-config
mountPath: /etc/ceph/
- name: ceph-csi-encryption-kms-config - name: ceph-csi-encryption-kms-config
mountPath: /etc/ceph-csi-encryption-kms-config/ mountPath: /etc/ceph-csi-encryption-kms-config/
- name: plugin-dir - name: plugin-dir
@ -190,6 +192,9 @@ spec:
- name: lib-modules - name: lib-modules
hostPath: hostPath:
path: /lib/modules path: /lib/modules
- name: ceph-config
configMap:
name: ceph-config
- name: ceph-csi-config - name: ceph-csi-config
configMap: configMap:
name: {{ .Values.configMapName | quote }} name: {{ .Values.configMapName | quote }}

View File

@ -181,6 +181,8 @@ spec:
readOnly: true readOnly: true
- name: ceph-csi-config - name: ceph-csi-config
mountPath: /etc/ceph-csi-config/ mountPath: /etc/ceph-csi-config/
- name: ceph-config
mountPath: /etc/ceph/
- name: ceph-csi-encryption-kms-config - name: ceph-csi-encryption-kms-config
mountPath: /etc/ceph-csi-encryption-kms-config/ mountPath: /etc/ceph-csi-encryption-kms-config/
- name: keys-tmp-dir - name: keys-tmp-dir
@ -213,6 +215,8 @@ spec:
mountPath: /etc/ceph-csi-config/ mountPath: /etc/ceph-csi-config/
- name: keys-tmp-dir - name: keys-tmp-dir
mountPath: /tmp/csi/keys mountPath: /tmp/csi/keys
- name: ceph-config
mountPath: /etc/ceph/
resources: resources:
{{ toYaml .Values.nodeplugin.plugin.resources | indent 12 }} {{ toYaml .Values.nodeplugin.plugin.resources | indent 12 }}
{{- end }} {{- end }}
@ -254,6 +258,9 @@ spec:
- name: lib-modules - name: lib-modules
hostPath: hostPath:
path: /lib/modules path: /lib/modules
- name: ceph-config
configMap:
name: ceph-config
- name: ceph-csi-config - name: ceph-csi-config
configMap: configMap:
name: {{ .Values.configMapName | quote }} name: {{ .Values.configMapName | quote }}

View File

@ -372,6 +372,26 @@ secret:
# Encryption passphrase # Encryption passphrase
encryptionPassphrase: test_passphrase encryptionPassphrase: test_passphrase
# This is a sample configmap that helps define a Ceph configuration as required
# by the CSI plugins.
# Sample ceph.conf available at
# https://github.com/ceph/ceph/blob/master/src/sample.ceph.conf Detailed
# documentation is available at
# https://docs.ceph.com/en/latest/rados/configuration/ceph-conf/
cephconf: |
[global]
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
# Workaround for http://tracker.ceph.com/issues/23446
fuse_set_user_groups = false
# ceph-fuse which uses libfuse2 by default has write buffer size of 2KiB
# adding 'fuse_big_writes = true' option by default to override this limit
# see https://github.com/ceph/ceph-csi/issues/1928
fuse_big_writes = true
######################################################### #########################################################
# Variables for 'internal' use please use with caution! # # Variables for 'internal' use please use with caution! #
######################################################### #########################################################

View File

@ -143,6 +143,8 @@ spec:
readOnly: true readOnly: true
- name: host-dev - name: host-dev
mountPath: /dev mountPath: /dev
- name: ceph-config
mountPath: /etc/ceph/
- name: ceph-csi-config - name: ceph-csi-config
mountPath: /etc/ceph-csi-config/ mountPath: /etc/ceph-csi-config/
- name: keys-tmp-dir - name: keys-tmp-dir
@ -181,6 +183,9 @@ spec:
- name: host-dev - name: host-dev
hostPath: hostPath:
path: /dev path: /dev
- name: ceph-config
configMap:
name: ceph-config
- name: ceph-csi-config - name: ceph-csi-config
configMap: configMap:
name: ceph-csi-config name: ceph-csi-config

View File

@ -94,6 +94,8 @@ spec:
mountPath: /dev mountPath: /dev
- name: host-mount - name: host-mount
mountPath: /run/mount mountPath: /run/mount
- name: ceph-config
mountPath: /etc/ceph/
- name: ceph-csi-config - name: ceph-csi-config
mountPath: /etc/ceph-csi-config/ mountPath: /etc/ceph-csi-config/
- name: keys-tmp-dir - name: keys-tmp-dir
@ -152,6 +154,9 @@ spec:
- name: host-mount - name: host-mount
hostPath: hostPath:
path: /run/mount path: /run/mount
- name: ceph-config
configMap:
name: ceph-config
- name: ceph-csi-config - name: ceph-csi-config
configMap: configMap:
name: ceph-csi-config name: ceph-csi-config

View File

@ -164,6 +164,8 @@ spec:
mountPath: /etc/ceph-csi-encryption-kms-config/ mountPath: /etc/ceph-csi-encryption-kms-config/
- name: keys-tmp-dir - name: keys-tmp-dir
mountPath: /tmp/csi/keys mountPath: /tmp/csi/keys
- name: ceph-config
mountPath: /etc/ceph/
- name: csi-rbdplugin-controller - name: csi-rbdplugin-controller
securityContext: securityContext:
privileged: true privileged: true
@ -187,6 +189,8 @@ spec:
mountPath: /etc/ceph-csi-config/ mountPath: /etc/ceph-csi-config/
- name: keys-tmp-dir - name: keys-tmp-dir
mountPath: /tmp/csi/keys mountPath: /tmp/csi/keys
- name: ceph-config
mountPath: /etc/ceph/
- name: liveness-prometheus - name: liveness-prometheus
image: quay.io/cephcsi/cephcsi:canary image: quay.io/cephcsi/cephcsi:canary
args: args:
@ -221,6 +225,9 @@ spec:
emptyDir: { emptyDir: {
medium: "Memory" medium: "Memory"
} }
- name: ceph-config
configMap:
name: ceph-config
- name: ceph-csi-config - name: ceph-csi-config
configMap: configMap:
name: ceph-csi-config name: ceph-csi-config

View File

@ -113,6 +113,8 @@ spec:
mountPath: /tmp/csi/keys mountPath: /tmp/csi/keys
- name: ceph-logdir - name: ceph-logdir
mountPath: /var/log/ceph mountPath: /var/log/ceph
- name: ceph-config
mountPath: /etc/ceph/
- name: liveness-prometheus - name: liveness-prometheus
securityContext: securityContext:
privileged: true privileged: true
@ -171,6 +173,9 @@ spec:
- name: lib-modules - name: lib-modules
hostPath: hostPath:
path: /lib/modules path: /lib/modules
- name: ceph-config
configMap:
name: ceph-config
- name: ceph-csi-config - name: ceph-csi-config
configMap: configMap:
name: ceph-csi-config name: ceph-csi-config

View File

@ -4,11 +4,6 @@
- [Pre-upgrade considerations](#pre-upgrade-considerations) - [Pre-upgrade considerations](#pre-upgrade-considerations)
- [Snapshot-controller and snapshot crd](#snapshot-controller-and-snapshot-crd) - [Snapshot-controller and snapshot crd](#snapshot-controller-and-snapshot-crd)
- [Snapshot API version support matrix](#snapshot-api-version-support-matrix) - [Snapshot API version support matrix](#snapshot-api-version-support-matrix)
- [Upgrading from v1.2 to v2.0](#upgrading-from-v12-to-v20)
- [Upgrading from v2.0 to v2.1](#upgrading-from-v20-to-v21)
- [Upgrading from v2.1 to v3.0](#upgrading-from-v21-to-v30)
- [Upgrading from v3.0 to v3.1](#upgrading-from-v30-to-v31)
- [Upgrading from v3.1 to v3.2](#upgrading-from-v31-to-v32)
- [Upgrading from v3.2 to v3.3](#upgrading-from-v32-to-v33) - [Upgrading from v3.2 to v3.3](#upgrading-from-v32-to-v33)
- [Upgrading from v3.3 to v3.4](#upgrading-from-v33-to-v34) - [Upgrading from v3.3 to v3.4](#upgrading-from-v33-to-v34)
- [Upgrading CephFS](#upgrading-cephfs) - [Upgrading CephFS](#upgrading-cephfs)
@ -65,34 +60,6 @@ controller and snapshot CRD. more info can be found
**Note:** We recommend to use {sidecar, controller, crds} of same version **Note:** We recommend to use {sidecar, controller, crds} of same version
## Upgrading from v1.2 to v2.0
Refer
[upgrade-from-v1.2-v2.0](https://github.com/ceph/ceph-csi/blob/v2.0.1/docs/ceph-csi-upgrade.md)
to upgrade from cephcsi v1.2 to v2.0
## Upgrading from v2.0 to v2.1
Refer
[upgrade-from-v2.0-v2.1](https://github.com/ceph/ceph-csi/blob/v2.1.2/docs/ceph-csi-upgrade.md)
to upgrade from cephcsi v2.0 to v2.1
## Upgrading from v2.1 to v3.0
Refer
[upgrade-from-v2.1-v3.0](https://github.com/ceph/ceph-csi/blob/v3.0.0/docs/ceph-csi-upgrade.md)
to upgrade from cephcsi v2.1 to v3.0
## Upgrading from v3.0 to v3.1
Refer [upgrade-from-v3.0-v3.1](https://github.com/ceph/ceph-csi/blob/v3.1.2/docs/ceph-csi-upgrade.md)
to upgrade from cephcsi v3.0 to v3.1
## Upgrading from v3.1 to v3.2
Refer [upgrade-from-v3.1-v3.2](https://github.com/ceph/ceph-csi/blob/v3.2.1/docs/ceph-csi-upgrade.md)
to upgrade from cephcsi v3.1 to v3.2
## Upgrading from v3.2 to v3.3 ## Upgrading from v3.2 to v3.3
Refer [upgrade-from-v3.2-v3.3](https://github.com/ceph/ceph-csi/blob/v3.3.1/docs/ceph-csi-upgrade.md) Refer [upgrade-from-v3.2-v3.3](https://github.com/ceph/ceph-csi/blob/v3.3.1/docs/ceph-csi-upgrade.md)

View File

@ -157,6 +157,12 @@ within the Ceph CSI plugin pods. To add a specific Ceph clusters configuration
details, refer to [Creating CSI configuration](../examples/README.md#creating-csi-configuration) details, refer to [Creating CSI configuration](../examples/README.md#creating-csi-configuration)
for more information. for more information.
**Deploy Ceph configuration ConfigMap for CSI pods:**
```bash
kubectl create -f ../example/ceph-config.yaml
```
**Deploy CSI sidecar containers:** **Deploy CSI sidecar containers:**
```bash ```bash

View File

@ -126,6 +126,12 @@ details, refer to [Creating CSI configuration for RBD based
provisioning](../examples/README.md#creating-csi-configuration-for-rbd-based-provisioning) provisioning](../examples/README.md#creating-csi-configuration-for-rbd-based-provisioning)
for more information. for more information.
**Deploy Ceph configuration ConfigMap for CSI pods:**
```bash
kubectl create -f ../example/ceph-config.yaml
```
**Deploy CSI sidecar containers:** **Deploy CSI sidecar containers:**
```bash ```bash

View File

@ -28,7 +28,7 @@ var (
cephfsDeamonSetName = "csi-cephfsplugin" cephfsDeamonSetName = "csi-cephfsplugin"
cephfsContainerName = "csi-cephfsplugin" cephfsContainerName = "csi-cephfsplugin"
cephfsDirPath = "../deploy/cephfs/kubernetes/" cephfsDirPath = "../deploy/cephfs/kubernetes/"
cephfsExamplePath = "../examples/cephfs/" cephfsExamplePath = examplePath + "cephfs/"
subvolumegroup = "e2e" subvolumegroup = "e2e"
fileSystemName = "myfs" fileSystemName = "myfs"
) )
@ -76,6 +76,19 @@ func createORDeleteCephfsResources(action kubectlAction) {
e2elog.Failf("failed to %s CSIDriver object with error %v", action, err) e2elog.Failf("failed to %s CSIDriver object with error %v", action, err)
} }
} }
cephConf, err := ioutil.ReadFile(examplePath + cephConfconfigMap)
if err != nil {
// createORDeleteCephfsResources is used for upgrade testing as cephConfConfigmap is
// newly added, discarding file not found error.
if !os.IsNotExist(err) {
e2elog.Failf("failed to read content from %s with error %v", examplePath+cephConfconfigMap, err)
}
} else {
err = retryKubectlInput(cephCSINamespace, action, string(cephConf), deployTimeout)
if err != nil {
e2elog.Failf("failed to %s ceph-conf configmap object with error %v", action, err)
}
}
data, err := replaceNamespaceInTemplate(cephfsDirPath + cephfsProvisioner) data, err := replaceNamespaceInTemplate(cephfsDirPath + cephfsProvisioner)
if err != nil { if err != nil {
e2elog.Failf("failed to read content from %s with error %v", cephfsDirPath+cephfsProvisioner, err) e2elog.Failf("failed to read content from %s with error %v", cephfsDirPath+cephfsProvisioner, err)

View File

@ -28,9 +28,11 @@ var (
rbdNodePluginRBAC = "csi-nodeplugin-rbac.yaml" rbdNodePluginRBAC = "csi-nodeplugin-rbac.yaml"
rbdNodePluginPSP = "csi-nodeplugin-psp.yaml" rbdNodePluginPSP = "csi-nodeplugin-psp.yaml"
configMap = "csi-config-map.yaml" configMap = "csi-config-map.yaml"
cephConfconfigMap = "ceph-conf.yaml"
csiDriverObject = "csidriver.yaml" csiDriverObject = "csidriver.yaml"
rbdDirPath = "../deploy/rbd/kubernetes/" rbdDirPath = "../deploy/rbd/kubernetes/"
rbdExamplePath = "../examples/rbd/" examplePath = "../examples/"
rbdExamplePath = examplePath + "/rbd/"
rbdDeploymentName = "csi-rbdplugin-provisioner" rbdDeploymentName = "csi-rbdplugin-provisioner"
rbdDaemonsetName = "csi-rbdplugin" rbdDaemonsetName = "csi-rbdplugin"
defaultRBDPool = "replicapool" defaultRBDPool = "replicapool"
@ -102,6 +104,19 @@ func createORDeleteRbdResources(action kubectlAction) {
e2elog.Failf("failed to %s CSIDriver object with error %v", action, err) e2elog.Failf("failed to %s CSIDriver object with error %v", action, err)
} }
} }
cephConf, err := ioutil.ReadFile(examplePath + cephConfconfigMap)
if err != nil {
// createORDeleteRbdResources is used for upgrade testing as cephConf Configmap is
// newly added, discarding file not found error.
if !os.IsNotExist(err) {
e2elog.Failf("failed to read content from %s with error %v", examplePath+cephConfconfigMap, err)
}
} else {
err = retryKubectlInput(cephCSINamespace, action, string(cephConf), deployTimeout)
if err != nil {
e2elog.Failf("failed to %s ceph-conf configmap object with error %v", action, err)
}
}
data, err := replaceNamespaceInTemplate(rbdDirPath + rbdProvisioner) data, err := replaceNamespaceInTemplate(rbdDirPath + rbdProvisioner)
if err != nil { if err != nil {
e2elog.Failf("failed to read content from %s with error %v", rbdDirPath+rbdProvisioner, err) e2elog.Failf("failed to read content from %s with error %v", rbdDirPath+rbdProvisioner, err)

28
examples/ceph-conf.yaml Normal file
View File

@ -0,0 +1,28 @@
---
# This is a sample configmap that helps define a Ceph configuration as required
# by the CSI plugins.
# Sample ceph.conf available at
# https://github.com/ceph/ceph/blob/master/src/sample.ceph.conf Detailed
# documentation is available at
# https://docs.ceph.com/en/latest/rados/configuration/ceph-conf/
apiVersion: v1
kind: ConfigMap
data:
ceph.conf: |
[global]
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
# Workaround for http://tracker.ceph.com/issues/23446
fuse_set_user_groups = false
# ceph-fuse which uses libfuse2 by default has write buffer size of 2KiB
# adding 'fuse_big_writes = true' option by default to override this limit
# see https://github.com/ceph/ceph-csi/issues/1928
fuse_big_writes = true
# keyring is a required key and its value should be empty
keyring: |
metadata:
name: ceph-config

76
go.mod
View File

@ -3,7 +3,7 @@ module github.com/ceph/ceph-csi
go 1.16 go 1.16
require ( require (
github.com/aws/aws-sdk-go v1.38.63 github.com/aws/aws-sdk-go v1.40.34
github.com/ceph/go-ceph v0.11.0 github.com/ceph/go-ceph v0.11.0
github.com/container-storage-interface/spec v1.5.0 github.com/container-storage-interface/spec v1.5.0
github.com/csi-addons/replication-lib-utils v0.2.0 github.com/csi-addons/replication-lib-utils v0.2.0
@ -11,27 +11,28 @@ require (
github.com/golang/protobuf v1.5.2 github.com/golang/protobuf v1.5.2
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/vault/api v1.0.5-0.20200902155336-f9d5ce5a171a github.com/hashicorp/vault/api v1.0.5-0.20200902155336-f9d5ce5a171a
github.com/kubernetes-csi/csi-lib-utils v0.10.0 github.com/kubernetes-csi/csi-lib-utils v0.10.0
github.com/kubernetes-csi/external-snapshotter/client/v4 v4.2.0 github.com/kubernetes-csi/external-snapshotter/client/v4 v4.2.0
github.com/libopenstorage/secrets v0.0.0-20210709082113-dde442ea20ec github.com/libopenstorage/secrets v0.0.0-20210709082113-dde442ea20ec
github.com/onsi/ginkgo v1.16.4 github.com/onsi/ginkgo v1.16.4
github.com/onsi/gomega v1.13.0 github.com/onsi/gomega v1.16.0
github.com/pborman/uuid v1.2.1 github.com/pborman/uuid v1.2.1
github.com/prometheus/client_golang v1.11.0 github.com/prometheus/client_golang v1.11.0
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2
google.golang.org/grpc v1.38.0 google.golang.org/grpc v1.40.0
k8s.io/api v0.22.0 k8s.io/api v0.22.1
k8s.io/apimachinery v0.22.0 k8s.io/apimachinery v0.22.1
k8s.io/client-go v12.0.0+incompatible k8s.io/client-go v12.0.0+incompatible
k8s.io/cloud-provider v1.22.0 k8s.io/cloud-provider v1.22.1
k8s.io/klog/v2 v2.9.0 k8s.io/klog/v2 v2.10.0
k8s.io/kubernetes v1.22.0 k8s.io/kubernetes v1.22.1
k8s.io/mount-utils v0.22.0 k8s.io/mount-utils v0.22.1
k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9 k8s.io/utils v0.0.0-20210802155522-efc7438f0176
sigs.k8s.io/controller-runtime v0.9.2 sigs.k8s.io/controller-runtime v0.10.0
) )
replace ( replace (
@ -41,35 +42,34 @@ replace (
github.com/hashicorp/vault/sdk => github.com/hashicorp/vault/sdk v0.1.14-0.20201116234512-b4d4137dfe8b github.com/hashicorp/vault/sdk => github.com/hashicorp/vault/sdk v0.1.14-0.20201116234512-b4d4137dfe8b
github.com/portworx/sched-ops => github.com/portworx/sched-ops v0.20.4-openstorage-rc3 github.com/portworx/sched-ops => github.com/portworx/sched-ops v0.20.4-openstorage-rc3
gomodules.xyz/jsonpatch/v2 => github.com/gomodules/jsonpatch/v2 v2.2.0 gomodules.xyz/jsonpatch/v2 => github.com/gomodules/jsonpatch/v2 v2.2.0
google.golang.org/grpc => google.golang.org/grpc v1.35.0
// //
// k8s.io/kubernetes depends on these k8s.io packages, but unversioned // k8s.io/kubernetes depends on these k8s.io packages, but unversioned
// //
k8s.io/api => k8s.io/api v0.22.0 k8s.io/api => k8s.io/api v0.22.1
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.22.0 k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.22.1
k8s.io/apimachinery => k8s.io/apimachinery v0.22.0 k8s.io/apimachinery => k8s.io/apimachinery v0.22.1
k8s.io/apiserver => k8s.io/apiserver v0.22.0 k8s.io/apiserver => k8s.io/apiserver v0.22.1
k8s.io/cli-runtime => k8s.io/cli-runtime v0.22.0 k8s.io/cli-runtime => k8s.io/cli-runtime v0.22.1
k8s.io/client-go => k8s.io/client-go v0.22.0 k8s.io/client-go => k8s.io/client-go v0.22.1
k8s.io/cloud-provider => k8s.io/cloud-provider v0.22.0 k8s.io/cloud-provider => k8s.io/cloud-provider v0.22.1
k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.22.0 k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.22.1
k8s.io/code-generator => k8s.io/code-generator v0.22.0 k8s.io/code-generator => k8s.io/code-generator v0.22.1
k8s.io/component-base => k8s.io/component-base v0.22.0 k8s.io/component-base => k8s.io/component-base v0.22.1
k8s.io/component-helpers => k8s.io/component-helpers v0.22.0 k8s.io/component-helpers => k8s.io/component-helpers v0.22.1
k8s.io/controller-manager => k8s.io/controller-manager v0.22.0 k8s.io/controller-manager => k8s.io/controller-manager v0.22.1
k8s.io/cri-api => k8s.io/cri-api v0.22.0 k8s.io/cri-api => k8s.io/cri-api v0.22.1
k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.22.0 k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.22.1
k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.22.0 k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.22.1
k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.22.0 k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.22.1
k8s.io/kube-proxy => k8s.io/kube-proxy v0.22.0 k8s.io/kube-proxy => k8s.io/kube-proxy v0.22.1
k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.22.0 k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.22.1
k8s.io/kubectl => k8s.io/kubectl v0.22.0 k8s.io/kubectl => k8s.io/kubectl v0.22.1
k8s.io/kubelet => k8s.io/kubelet v0.22.0 k8s.io/kubelet => k8s.io/kubelet v0.22.1
k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.22.0 k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.22.1
k8s.io/metrics => k8s.io/metrics v0.22.0 k8s.io/metrics => k8s.io/metrics v0.22.1
k8s.io/mount-utils => k8s.io/mount-utils v0.22.0 k8s.io/mount-utils => k8s.io/mount-utils v0.22.1
k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.22.0 k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.22.1
k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.22.0 k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.22.1
) )
// This tag doesn't exist, but is imported by github.com/portworx/sched-ops. // This tag doesn't exist, but is imported by github.com/portworx/sched-ops.

152
go.sum
View File

@ -133,11 +133,12 @@ github.com/aws/aws-sdk-go v1.25.41/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpi
github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go v1.35.24/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= github.com/aws/aws-sdk-go v1.35.24/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
github.com/aws/aws-sdk-go v1.38.49/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.38.49/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go v1.38.63 h1:BqPxe0sujTRTbir6OWj0f1VmeJcAIv7ZhTCAhaU1zmE= github.com/aws/aws-sdk-go v1.40.34 h1:SBYmodndE2d4AYucuuJnOXk4MD1SFbucoIdpwKVKeSA=
github.com/aws/aws-sdk-go v1.38.63/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.40.34/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJyXg=
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@ -176,10 +177,13 @@ github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJ
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381/go.mod h1:e5+USP2j8Le2M0Jo3qKPFnNhuo1wueU4nWHCXBOfQ14= github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381/go.mod h1:e5+USP2j8Le2M0Jo3qKPFnNhuo1wueU4nWHCXBOfQ14=
github.com/cloudfoundry/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:Zv7xtAh/T/tmfZlxpESaWWiWOdiJz2GfbBYxImuI6T4= github.com/cloudfoundry/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:Zv7xtAh/T/tmfZlxpESaWWiWOdiJz2GfbBYxImuI6T4=
github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313/go.mod h1:P1wt9Z3DP8O6W3rvwCt0REIlshg1InHImaLW0t3ObY0= github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313/go.mod h1:P1wt9Z3DP8O6W3rvwCt0REIlshg1InHImaLW0t3ObY0=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
@ -269,7 +273,12 @@ github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484/go.mod h1:Ro8st/El
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw=
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
@ -367,6 +376,8 @@ github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4er
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
@ -755,7 +766,6 @@ github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
@ -765,8 +775,9 @@ github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
@ -1030,8 +1041,9 @@ go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE=
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@ -1072,6 +1084,8 @@ golang.org/x/exp v0.0.0-20210220032938-85be41e4509f/go.mod h1:I6l2HNBLBZEcrOoCpy
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -1143,8 +1157,9 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 h1:ADo5wSpq2gqaCGQWzk7S5vd//0iyyLeAratkEoG5dLE=
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -1168,6 +1183,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -1242,8 +1258,9 @@ golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo=
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
@ -1266,14 +1283,15 @@ golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/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-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@ -1411,8 +1429,32 @@ google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/grpc v1.35.0 h1:TwIQcH3es+MojMVojxxfQ3l3OF2KzlRxML2xZq0kRo8= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
@ -1471,6 +1513,7 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@ -1479,28 +1522,28 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.22.0 h1:elCpMZ9UE8dLdYxr55E06TmSeji9I3KH494qH70/y+c= k8s.io/api v0.22.1 h1:ISu3tD/jRhYfSW8jI/Q1e+lRxkR7w9UwQEZ7FgslrwY=
k8s.io/api v0.22.0/go.mod h1:0AoXXqst47OI/L0oGKq9DG61dvGRPXs7X4/B7KyjBCU= k8s.io/api v0.22.1/go.mod h1:bh13rkTp3F1XEaLGykbyRD2QaTTzPm0e/BMd8ptFONY=
k8s.io/apiextensions-apiserver v0.22.0 h1:QTuZIQggaE7N8FTjur+1zxLmEPziphK7nNm8t+VNO3g= k8s.io/apiextensions-apiserver v0.22.1 h1:YSJYzlFNFSfUle+yeEXX0lSQyLEoxoPJySRupepb0gE=
k8s.io/apiextensions-apiserver v0.22.0/go.mod h1:+9w/QQC/lwH2qTbpqndXXjwBgidlSmytvIUww16UACE= k8s.io/apiextensions-apiserver v0.22.1/go.mod h1:HeGmorjtRmRLE+Q8dJu6AYRoZccvCMsghwS8XTUYb2c=
k8s.io/apimachinery v0.22.0 h1:CqH/BdNAzZl+sr3tc0D3VsK3u6ARVSo3GWyLmfIjbP0= k8s.io/apimachinery v0.22.1 h1:DTARnyzmdHMz7bFWFDDm22AM4pLWTQECMpRTFu2d2OM=
k8s.io/apimachinery v0.22.0/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
k8s.io/apiserver v0.22.0 h1:KZh2asnRBjawLLfPOi6qiD+A2jaNt31HCnZG6AX3Qcs= k8s.io/apiserver v0.22.1 h1:Ul9Iv8OMB2s45h2tl5XWPpAZo1VPIJ/6N+MESeed7L8=
k8s.io/apiserver v0.22.0/go.mod h1:04kaIEzIQrTGJ5syLppQWvpkLJXQtJECHmae+ZGc/nc= k8s.io/apiserver v0.22.1/go.mod h1:2mcM6dzSt+XndzVQJX21Gx0/Klo7Aen7i0Ai6tIa400=
k8s.io/cli-runtime v0.22.0/go.mod h1:An6zELQ7udUI0GaXvkuMqyopPA14dIgNqpH8cZu1vig= k8s.io/cli-runtime v0.22.1/go.mod h1:YqwGrlXeEk15Yn3em2xzr435UGwbrCw5x+COQoTYfoo=
k8s.io/client-go v0.22.0 h1:sD6o9O6tCwUKCENw8v+HFsuAbq2jCu8cWC61/ydwA50= k8s.io/client-go v0.22.1 h1:jW0ZSHi8wW260FvcXHkIa0NLxFBQszTlhiAVsU5mopw=
k8s.io/client-go v0.22.0/go.mod h1:GUjIuXR5PiEv/RVK5OODUsm6eZk7wtSWZSaSJbpFdGg= k8s.io/client-go v0.22.1/go.mod h1:BquC5A4UOo4qVDUtoc04/+Nxp1MeHcVc1HJm1KmG8kk=
k8s.io/cloud-provider v0.22.0 h1:eK0swLQ1TZCLefRbgwEo/ZS4ZDo6FkOJDkDIBITshyw= k8s.io/cloud-provider v0.22.1 h1:bxNgHd0chiPpXQ8jzibRrbwuCRPrTgQiFSLbgVebzHs=
k8s.io/cloud-provider v0.22.0/go.mod h1:UsQNOxrStwOXoDfVNgEbKgcQt2BYuHGKobixm0zKTis= k8s.io/cloud-provider v0.22.1/go.mod h1:Dm3xJ4j3l88rZ0LBCRLrt7V9Pz0avRAzZSU6ENwYnrw=
k8s.io/cluster-bootstrap v0.22.0/go.mod h1:VeZXiGfH+yfnC2KtvkSwNTAqahg6yiCV/szbWpoI+3k= k8s.io/cluster-bootstrap v0.22.1/go.mod h1:dSWw6aox00AA9YCdRDY+ca7TVtoXRzuLpDxhV6HPevk=
k8s.io/code-generator v0.22.0/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o= k8s.io/code-generator v0.22.1/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
k8s.io/component-base v0.22.0 h1:ZTmX8hUqH9T9gc0mM42O+KDgtwTYbVTt2MwmLP0eK8A= k8s.io/component-base v0.22.1 h1:SFqIXsEN3v3Kkr1bS6rstrs1wd45StJqbtgbQ4nRQdo=
k8s.io/component-base v0.22.0/go.mod h1:SXj6Z+V6P6GsBhHZVbWCw9hFjUdUYnJerlhhPnYCBCg= k8s.io/component-base v0.22.1/go.mod h1:0D+Bl8rrnsPN9v0dyYvkqFfBeAd4u7n77ze+p8CMiPo=
k8s.io/component-helpers v0.22.0 h1:OoTOtxTkg/T16FRS1K/WfABzxliTCq3RTbFHMBSod/o= k8s.io/component-helpers v0.22.1 h1:f8pdhKNQbsCMQa6E9ipVlO8G6WFXnKbEDVcWB8n/HkA=
k8s.io/component-helpers v0.22.0/go.mod h1:YNIbQI59ayNiU8JHlPIxVkOUYycbKhk5Niy0pcyJOEY= k8s.io/component-helpers v0.22.1/go.mod h1:QvBcDbX+qU5I2tMZABBF5fRwAlQwiv771IGBHK9WYh4=
k8s.io/controller-manager v0.22.0/go.mod h1:KCFcmFIjh512sVIm1EhAPJ+4miASDvbZA5eO/2nbr2M= k8s.io/controller-manager v0.22.1/go.mod h1:HN5qzvZs8A4fd/xuqDZwqe+Nsz249a2Kbq/YqZ903n8=
k8s.io/cri-api v0.22.0/go.mod h1:mj5DGUtElRyErU5AZ8EM0ahxbElYsaLAMTPhLPQ40Eg= k8s.io/cri-api v0.22.1/go.mod h1:mj5DGUtElRyErU5AZ8EM0ahxbElYsaLAMTPhLPQ40Eg=
k8s.io/csi-translation-lib v0.22.0/go.mod h1:wb6bRqDth2jcHfty7mLdQc7nfknHhIkAlAZgSgplXhc= k8s.io/csi-translation-lib v0.22.1/go.mod h1:3MuSQekn6WWgWJk5vgufqoTjB4jqBEe04TtimXjubcE=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/klog v0.3.0 h1:0VPpR+sizsiivjIfIAQH/rl8tan6jvWkS7lU+0di3lE= k8s.io/klog v0.3.0 h1:0VPpR+sizsiivjIfIAQH/rl8tan6jvWkS7lU+0di3lE=
@ -1508,33 +1551,34 @@ k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
k8s.io/kube-aggregator v0.22.0/go.mod h1:zHTepg0Q4tKzru7Pwg1QYHWrU/wrvIXM8hUdDAH66qg= k8s.io/klog/v2 v2.10.0 h1:R2HDMDJsHVTHA2n4RjwbeYXdOcBymXdX/JRb1v0VGhE=
k8s.io/kube-controller-manager v0.22.0/go.mod h1:E/EYMoCj8bbPRmu19JF4B9QLyQL8Tywg+9Q/rg+F80U= k8s.io/klog/v2 v2.10.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
k8s.io/kube-aggregator v0.22.1/go.mod h1:VbmI+8fUeCPkzSvarWTrlIGEgUGEGI/66SFajDQ0Pdc=
k8s.io/kube-controller-manager v0.22.1/go.mod h1:TUXvgmBcDmpYyzDBW+naL0Ljo7IADv6HkYbxg0MLdJY=
k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kube-proxy v0.22.0/go.mod h1:2ckKSCr8kZ0kNNCgxM7lt0g5CAaY767djotK4AEFPmI= k8s.io/kube-proxy v0.22.1/go.mod h1:Rj3/mSZuSKfDY7XVbDgb12UwiQHy265LOwpK/yR2rtc=
k8s.io/kube-scheduler v0.22.0/go.mod h1:n6tdYAiaoqXGLazCwIpOEg42qby0VMDs1KmN4DjQf50= k8s.io/kube-scheduler v0.22.1/go.mod h1:32YH9ef2m03E5LfD/H8TMTSppWq3Hav8LON9e+NGC3k=
k8s.io/kubectl v0.22.0 h1:EBb7xLUaidG/YXAI5AXam3lK2VlnoFShhlMjnJVTbGA= k8s.io/kubectl v0.22.1 h1:kpXO+ajPNTzAVLDM9pAzCsWH9MtCMr92zpcvXMt7P6E=
k8s.io/kubectl v0.22.0/go.mod h1:eeuP92uZbVL2UnOaf0nj9OjtI0hi/nekHU+0isURer0= k8s.io/kubectl v0.22.1/go.mod h1:mjAOgEbMNMtZWxnfM6jd+nPjPsaoLqO5xanc78WcSbw=
k8s.io/kubelet v0.22.0 h1:cVu1RWuikW9dMJSXDG2f6k81u7NuURrnzphgY/tQxZE= k8s.io/kubelet v0.22.1 h1:ssJ3DxLXtuC3lG4Gif8h1krw5ahSi1fNnzfyZW+Cn/Y=
k8s.io/kubelet v0.22.0/go.mod h1:CMdsuh9OFgbpeE+n46GpVMDecLlI0HxSRHMoNrTmJk4= k8s.io/kubelet v0.22.1/go.mod h1:rZuP1msr5NH7IGApW60DYFR3Cs3On4ftWLMJRfg+iU4=
k8s.io/kubernetes v1.22.0 h1:zROjVlA1qSthvMnP7XeCzkRaqkE28CY3w+PM8qC0ZaA= k8s.io/kubernetes v1.22.1 h1:xE8OqErmoV/e67JV6/zExQA5sLTb44iW9fprXS2lL7I=
k8s.io/kubernetes v1.22.0/go.mod h1:IGQZrV02n2IBp52+/YwLVMurCEQPKXJ/k8hU3mqEOuA= k8s.io/kubernetes v1.22.1/go.mod h1:IGQZrV02n2IBp52+/YwLVMurCEQPKXJ/k8hU3mqEOuA=
k8s.io/legacy-cloud-providers v0.22.0/go.mod h1:2tKlbeA9r0OYnBHyqHcnO1EoAeqYXw2IZH99DYwwErM= k8s.io/legacy-cloud-providers v0.22.1/go.mod h1:5ejdiQhOxTigKFrFcMvulMCyxxffmkZpk/WMgnknkwI=
k8s.io/metrics v0.22.0/go.mod h1:eYnwafAUNLLpVmY/msoq0RKIKH5C4TzfjKnMZ0Xrt3A= k8s.io/metrics v0.22.1/go.mod h1:i/ZNap89UkV1gLa26dn7fhKAdheJaKy+moOqJbiif7E=
k8s.io/mount-utils v0.22.0 h1:yNUW+1HO+ZhYDEZ7a/14Un7nqW8Md4zeuLnenGCGDi4= k8s.io/mount-utils v0.22.1 h1:3xMxnOKobldBJMLAEpsC9Y3Drw1aaXz/fhTtYes4VTE=
k8s.io/mount-utils v0.22.0/go.mod h1:gUi5ht+05KHYc/vJ9q9wbvG3MCYBeOsB5FdTyM60Pzo= k8s.io/mount-utils v0.22.1/go.mod h1:gUi5ht+05KHYc/vJ9q9wbvG3MCYBeOsB5FdTyM60Pzo=
k8s.io/pod-security-admission v0.22.0/go.mod h1:xKTKO4nzxLDROM+RRndSU7kCZc2XcBYRKLYS+gYuqfo= k8s.io/pod-security-admission v0.22.1/go.mod h1:JHgUW6u0VaFaRv2dWh/VYmKL5Hd8ZQCSVuegofSx+rY=
k8s.io/sample-apiserver v0.22.0/go.mod h1:Bkl0f9E1Moxwjvqct7kzDlTvNUTavsworU5FTPlVooA= k8s.io/sample-apiserver v0.22.1/go.mod h1:1HfRH0fcTF33VZnwAN7fdq/vA+aF1iAhKCWdzKAX7iI=
k8s.io/system-validators v1.5.0/go.mod h1:bPldcLgkIUK22ALflnsXk8pvkTEndYdNuaHH6gRrl0Q= k8s.io/system-validators v1.5.0/go.mod h1:bPldcLgkIUK22ALflnsXk8pvkTEndYdNuaHH6gRrl0Q=
k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210527160623-6fdb442a123b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9 h1:imL9YgXQ9p7xmPzHFm/vVd/cF78jad+n4wK1ABwYtMM=
k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210802155522-efc7438f0176 h1:Mx0aa+SUAcNRQbs5jUzV8lkDlGFU8laZsY9jrcVX5SY=
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
layeh.com/radius v0.0.0-20190322222518-890bc1058917/go.mod h1:fywZKyu//X7iRzaxLgPWsvc0L26IUpVvE/aeIL2JtIQ= layeh.com/radius v0.0.0-20190322222518-890bc1058917/go.mod h1:fywZKyu//X7iRzaxLgPWsvc0L26IUpVvE/aeIL2JtIQ=
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
@ -1548,8 +1592,8 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22 h1:fmRfl9WJ4ApJn7LxNuED4m0t18qivVQOxP6aAYG9J6c= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22 h1:fmRfl9WJ4ApJn7LxNuED4m0t18qivVQOxP6aAYG9J6c=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/controller-runtime v0.2.2/go.mod h1:9dyohw3ZtoXQuV1e766PHUn+cmrRCIcBh6XIMFNMZ+I= sigs.k8s.io/controller-runtime v0.2.2/go.mod h1:9dyohw3ZtoXQuV1e766PHUn+cmrRCIcBh6XIMFNMZ+I=
sigs.k8s.io/controller-runtime v0.9.2 h1:MnCAsopQno6+hI9SgJHKddzXpmv2wtouZz6931Eax+Q= sigs.k8s.io/controller-runtime v0.10.0 h1:HgyZmMpjUOrtkaFtCnfxsR1bGRuFoAczSNbn2MoKj5U=
sigs.k8s.io/controller-runtime v0.9.2/go.mod h1:TxzMCHyEUpaeuOiZx/bIdc2T81vfs/aKdvJt9wuu0zk= sigs.k8s.io/controller-runtime v0.10.0/go.mod h1:GCdh6kqV6IY4LK0JLwX0Zm6g233RtVGdb/f0+KSfprg=
sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g= sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g=
sigs.k8s.io/kustomize/cmd/config v0.9.13/go.mod h1:7547FLF8W/lTaDf0BDqFTbZxM9zqwEJqCKN9sSR0xSs= sigs.k8s.io/kustomize/cmd/config v0.9.13/go.mod h1:7547FLF8W/lTaDf0BDqFTbZxM9zqwEJqCKN9sSR0xSs=
sigs.k8s.io/kustomize/kustomize/v4 v4.2.0/go.mod h1:MOkR6fmhwG7hEDRXBYELTi5GSFcLwfqwzTRHW3kv5go= sigs.k8s.io/kustomize/kustomize/v4 v4.2.0/go.mod h1:MOkR6fmhwG7hEDRXBYELTi5GSFcLwfqwzTRHW3kv5go=

View File

@ -20,6 +20,7 @@ import (
"context" "context"
"fmt" "fmt"
cerrors "github.com/ceph/ceph-csi/internal/cephfs/errors"
"github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util"
"github.com/ceph/ceph-csi/internal/util/log" "github.com/ceph/ceph-csi/internal/util/log"
) )
@ -47,7 +48,7 @@ func (vo *volumeOptions) getFscID(ctx context.Context) (int64, error) {
log.ErrorLog(ctx, "failed to list volume %s", vo.FsName) log.ErrorLog(ctx, "failed to list volume %s", vo.FsName)
return 0, ErrVolumeNotFound return 0, cerrors.ErrVolumeNotFound
} }
func (vo *volumeOptions) getMetadataPool(ctx context.Context) (string, error) { func (vo *volumeOptions) getMetadataPool(ctx context.Context) (string, error) {

View File

@ -20,6 +20,7 @@ import (
"context" "context"
"errors" "errors"
cerrors "github.com/ceph/ceph-csi/internal/cephfs/errors"
"github.com/ceph/ceph-csi/internal/util/log" "github.com/ceph/ceph-csi/internal/util/log"
) )
@ -48,13 +49,13 @@ func (cs cephFSCloneState) toError() error {
case cephFSCloneComplete: case cephFSCloneComplete:
return nil return nil
case cephFSCloneError: case cephFSCloneError:
return ErrInvalidClone return cerrors.ErrInvalidClone
case cephFSCloneInprogress: case cephFSCloneInprogress:
return ErrCloneInProgress return cerrors.ErrCloneInProgress
case cephFSClonePending: case cephFSClonePending:
return ErrClonePending return cerrors.ErrClonePending
case cephFSCloneFailed: case cephFSCloneFailed:
return ErrCloneFailed return cerrors.ErrCloneFailed
} }
return nil return nil
@ -90,7 +91,7 @@ func createCloneFromSubvolume(ctx context.Context, volID, cloneID volumeID, volO
// In case the snap is already unprotected we get ErrSnapProtectionExist error code // In case the snap is already unprotected we get ErrSnapProtectionExist error code
// in that case we are safe and we could discard this error and we are good to go // in that case we are safe and we could discard this error and we are good to go
// ahead with deletion // ahead with deletion
if !errors.Is(err, ErrSnapProtectionExist) { if !errors.Is(err, cerrors.ErrSnapProtectionExist) {
log.ErrorLog(ctx, "failed to unprotect snapshot %s %v", snapshotID, err) log.ErrorLog(ctx, "failed to unprotect snapshot %s %v", snapshotID, err)
} }
} }
@ -137,7 +138,7 @@ func createCloneFromSubvolume(ctx context.Context, volID, cloneID volumeID, volO
// In case the snap is already unprotected we get ErrSnapProtectionExist error code // In case the snap is already unprotected we get ErrSnapProtectionExist error code
// in that case we are safe and we could discard this error and we are good to go // in that case we are safe and we could discard this error and we are good to go
// ahead with deletion // ahead with deletion
if !errors.Is(err, ErrSnapProtectionExist) { if !errors.Is(err, cerrors.ErrSnapProtectionExist) {
log.ErrorLog(ctx, "failed to unprotect snapshot %s %v", snapshotID, err) log.ErrorLog(ctx, "failed to unprotect snapshot %s %v", snapshotID, err)
return err return err
@ -161,7 +162,7 @@ func cleanupCloneFromSubvolumeSnapshot(
snapShotID := cloneID snapShotID := cloneID
snapInfo, err := parentVolOpt.getSnapshotInfo(ctx, snapShotID, volID) snapInfo, err := parentVolOpt.getSnapshotInfo(ctx, snapShotID, volID)
if err != nil { if err != nil {
if errors.Is(err, ErrSnapNotFound) { if errors.Is(err, cerrors.ErrSnapNotFound) {
return nil return nil
} }
@ -189,7 +190,7 @@ func cleanupCloneFromSubvolumeSnapshot(
// isCloneRetryError returns true if the clone error is pending,in-progress // isCloneRetryError returns true if the clone error is pending,in-progress
// error. // error.
func isCloneRetryError(err error) bool { func isCloneRetryError(err error) bool {
return errors.Is(err, ErrCloneInProgress) || errors.Is(err, ErrClonePending) return errors.Is(err, cerrors.ErrCloneInProgress) || errors.Is(err, cerrors.ErrClonePending)
} }
func createCloneFromSnapshot( func createCloneFromSnapshot(

View File

@ -19,6 +19,8 @@ package cephfs
import ( import (
"testing" "testing"
cerrors "github.com/ceph/ceph-csi/internal/cephfs/errors"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -26,10 +28,10 @@ func TestCloneStateToError(t *testing.T) {
t.Parallel() t.Parallel()
errorState := make(map[cephFSCloneState]error) errorState := make(map[cephFSCloneState]error)
errorState[cephFSCloneComplete] = nil errorState[cephFSCloneComplete] = nil
errorState[cephFSCloneError] = ErrInvalidClone errorState[cephFSCloneError] = cerrors.ErrInvalidClone
errorState[cephFSCloneInprogress] = ErrCloneInProgress errorState[cephFSCloneInprogress] = cerrors.ErrCloneInProgress
errorState[cephFSClonePending] = ErrClonePending errorState[cephFSClonePending] = cerrors.ErrClonePending
errorState[cephFSCloneFailed] = ErrCloneFailed errorState[cephFSCloneFailed] = cerrors.ErrCloneFailed
for state, err := range errorState { for state, err := range errorState {
assert.Equal(t, state.toError(), err) assert.Equal(t, state.toError(), err)

View File

@ -21,6 +21,7 @@ import (
"errors" "errors"
"fmt" "fmt"
cerrors "github.com/ceph/ceph-csi/internal/cephfs/errors"
csicommon "github.com/ceph/ceph-csi/internal/csi-common" csicommon "github.com/ceph/ceph-csi/internal/csi-common"
"github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util"
"github.com/ceph/ceph-csi/internal/util/log" "github.com/ceph/ceph-csi/internal/util/log"
@ -119,7 +120,7 @@ func checkContentSource(
snapshotID := req.VolumeContentSource.GetSnapshot().GetSnapshotId() snapshotID := req.VolumeContentSource.GetSnapshot().GetSnapshotId()
volOpt, _, sid, err := newSnapshotOptionsFromID(ctx, snapshotID, cr) volOpt, _, sid, err := newSnapshotOptionsFromID(ctx, snapshotID, cr)
if err != nil { if err != nil {
if errors.Is(err, ErrSnapNotFound) { if errors.Is(err, cerrors.ErrSnapNotFound) {
return nil, nil, nil, status.Error(codes.NotFound, err.Error()) return nil, nil, nil, status.Error(codes.NotFound, err.Error())
} }
@ -132,7 +133,7 @@ func checkContentSource(
volID := req.VolumeContentSource.GetVolume().GetVolumeId() volID := req.VolumeContentSource.GetVolume().GetVolumeId()
parentVol, pvID, err := newVolumeOptionsFromVolID(ctx, volID, nil, req.Secrets) parentVol, pvID, err := newVolumeOptionsFromVolID(ctx, volID, nil, req.Secrets)
if err != nil { if err != nil {
if !errors.Is(err, ErrVolumeNotFound) { if !errors.Is(err, cerrors.ErrVolumeNotFound) {
return nil, nil, nil, status.Error(codes.NotFound, err.Error()) return nil, nil, nil, status.Error(codes.NotFound, err.Error())
} }
@ -146,7 +147,7 @@ func checkContentSource(
} }
// CreateVolume creates a reservation and the volume in backend, if it is not already present. // CreateVolume creates a reservation and the volume in backend, if it is not already present.
// nolint:gocognit,gocyclo,nestif,cyclop // TODO: reduce complexity // nolint:gocyclo,cyclop // TODO: reduce complexity
func (cs *ControllerServer) CreateVolume( func (cs *ControllerServer) CreateVolume(
ctx context.Context, ctx context.Context,
req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) { req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) {
@ -187,7 +188,6 @@ func (cs *ControllerServer) CreateVolume(
if req.GetCapacityRange() != nil { if req.GetCapacityRange() != nil {
volOptions.Size = util.RoundOffBytes(req.GetCapacityRange().GetRequiredBytes()) volOptions.Size = util.RoundOffBytes(req.GetCapacityRange().GetRequiredBytes())
} }
// TODO need to add check for 0 volume size
parentVol, pvID, sID, err := checkContentSource(ctx, req, cr) parentVol, pvID, sID, err := checkContentSource(ctx, req, cr)
if err != nil { if err != nil {
@ -208,31 +208,6 @@ func (cs *ControllerServer) CreateVolume(
// TODO return error message if requested vol size greater than found volume return error // TODO return error message if requested vol size greater than found volume return error
if vID != nil { if vID != nil {
if sID != nil || pvID != nil {
// while cloning the volume the size is not populated properly to the new volume now.
// it will be fixed in cephfs soon with the parentvolume size. Till then by below
// resize we are making sure we return or satisfy the requested size by setting the size
// explicitly
err = volOptions.resizeVolume(ctx, volumeID(vID.FsSubvolName), volOptions.Size)
if err != nil {
purgeErr := volOptions.purgeVolume(ctx, volumeID(vID.FsSubvolName), false)
if purgeErr != nil {
log.ErrorLog(ctx, "failed to delete volume %s: %v", requestName, purgeErr)
// All errors other than ErrVolumeNotFound should return an error back to the caller
if !errors.Is(purgeErr, ErrVolumeNotFound) {
return nil, status.Error(codes.Internal, purgeErr.Error())
}
}
errUndo := undoVolReservation(ctx, volOptions, *vID, secret)
if errUndo != nil {
log.WarningLog(ctx, "failed undoing reservation of volume: %s (%s)",
requestName, errUndo)
}
log.ErrorLog(ctx, "failed to expand volume %s: %v", volumeID(vID.FsSubvolName), err)
return nil, status.Error(codes.Internal, err.Error())
}
}
volumeContext := req.GetParameters() volumeContext := req.GetParameters()
volumeContext["subvolumeName"] = vID.FsSubvolName volumeContext["subvolumeName"] = vID.FsSubvolName
volumeContext["subvolumePath"] = volOptions.RootPath volumeContext["subvolumePath"] = volOptions.RootPath
@ -288,7 +263,7 @@ func (cs *ControllerServer) CreateVolume(
if purgeErr != nil { if purgeErr != nil {
log.ErrorLog(ctx, "failed to delete volume %s: %v", vID.FsSubvolName, purgeErr) log.ErrorLog(ctx, "failed to delete volume %s: %v", vID.FsSubvolName, purgeErr)
// All errors other than ErrVolumeNotFound should return an error back to the caller // All errors other than ErrVolumeNotFound should return an error back to the caller
if !errors.Is(purgeErr, ErrVolumeNotFound) { if !errors.Is(purgeErr, cerrors.ErrVolumeNotFound) {
// If the subvolume deletion is failed, we should not cleanup // If the subvolume deletion is failed, we should not cleanup
// the OMAP entry it will stale subvolume in cluster. // the OMAP entry it will stale subvolume in cluster.
// set err=nil so that when we get the request again we can get // set err=nil so that when we get the request again we can get
@ -375,7 +350,7 @@ func (cs *ControllerServer) DeleteVolume(
log.ErrorLog(ctx, "Error returned from newVolumeOptionsFromVolID: %v", err) log.ErrorLog(ctx, "Error returned from newVolumeOptionsFromVolID: %v", err)
// All errors other than ErrVolumeNotFound should return an error back to the caller // All errors other than ErrVolumeNotFound should return an error back to the caller
if !errors.Is(err, ErrVolumeNotFound) { if !errors.Is(err, cerrors.ErrVolumeNotFound) {
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }
@ -413,11 +388,11 @@ func (cs *ControllerServer) DeleteVolume(
if err = volOptions.purgeVolume(ctx, volumeID(vID.FsSubvolName), false); err != nil { if err = volOptions.purgeVolume(ctx, volumeID(vID.FsSubvolName), false); err != nil {
log.ErrorLog(ctx, "failed to delete volume %s: %v", volID, err) log.ErrorLog(ctx, "failed to delete volume %s: %v", volID, err)
if errors.Is(err, ErrVolumeHasSnapshots) { if errors.Is(err, cerrors.ErrVolumeHasSnapshots) {
return nil, status.Error(codes.FailedPrecondition, err.Error()) return nil, status.Error(codes.FailedPrecondition, err.Error())
} }
if !errors.Is(err, ErrVolumeNotFound) { if !errors.Is(err, cerrors.ErrVolumeNotFound) {
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }
} }
@ -554,7 +529,7 @@ func (cs *ControllerServer) CreateSnapshot(
return nil, status.Error(codes.NotFound, err.Error()) return nil, status.Error(codes.NotFound, err.Error())
} }
if errors.Is(err, ErrVolumeNotFound) { if errors.Is(err, cerrors.ErrVolumeNotFound) {
return nil, status.Error(codes.NotFound, err.Error()) return nil, status.Error(codes.NotFound, err.Error())
} }
@ -598,7 +573,7 @@ func (cs *ControllerServer) CreateSnapshot(
// Check error code value against ErrInvalidCommand to understand the cluster // Check error code value against ErrInvalidCommand to understand the cluster
// support it or not, It's safe to evaluate as the filtering // support it or not, It's safe to evaluate as the filtering
// is already done from getSubVolumeInfo() and send out the error here. // is already done from getSubVolumeInfo() and send out the error here.
if errors.Is(err, ErrInvalidCommand) { if errors.Is(err, cerrors.ErrInvalidCommand) {
return nil, status.Error( return nil, status.Error(
codes.FailedPrecondition, codes.FailedPrecondition,
"subvolume info command not supported in current ceph cluster") "subvolume info command not supported in current ceph cluster")
@ -775,7 +750,7 @@ func (cs *ControllerServer) DeleteSnapshot(
// or partially complete (snap and snapOMap are garbage collected already), hence return // or partially complete (snap and snapOMap are garbage collected already), hence return
// success as deletion is complete // success as deletion is complete
return &csi.DeleteSnapshotResponse{}, nil return &csi.DeleteSnapshotResponse{}, nil
case errors.Is(err, ErrSnapNotFound): case errors.Is(err, cerrors.ErrSnapNotFound):
err = undoSnapReservation(ctx, volOpt, *sid, sid.FsSnapshotName, cr) err = undoSnapReservation(ctx, volOpt, *sid, sid.FsSnapshotName, cr)
if err != nil { if err != nil {
log.ErrorLog(ctx, "failed to remove reservation for snapname (%s) with backing snap (%s) (%s)", log.ErrorLog(ctx, "failed to remove reservation for snapname (%s) with backing snap (%s) (%s)",
@ -785,7 +760,7 @@ func (cs *ControllerServer) DeleteSnapshot(
} }
return &csi.DeleteSnapshotResponse{}, nil return &csi.DeleteSnapshotResponse{}, nil
case errors.Is(err, ErrVolumeNotFound): case errors.Is(err, cerrors.ErrVolumeNotFound):
// if the error is ErrVolumeNotFound, the subvolume is already deleted // if the error is ErrVolumeNotFound, the subvolume is already deleted
// from backend, Hence undo the omap entries and return success // from backend, Hence undo the omap entries and return success
log.ErrorLog(ctx, "Volume not present") log.ErrorLog(ctx, "Volume not present")

View File

@ -14,51 +14,51 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package cephfs package errors
import ( import (
"errors" coreError "errors"
) )
// Error strings for comparison with CLI errors. // Error strings for comparison with CLI errors.
const ( const (
// volumeNotEmpty is returned when the volume is not empty. // VolumeNotEmpty is returned when the volume is not empty.
volumeNotEmpty = "Directory not empty" VolumeNotEmpty = "Directory not empty"
) )
var ( var (
// ErrCloneInProgress is returned when snapshot clone state is `in progress`. // ErrCloneInProgress is returned when snapshot clone state is `in progress`.
ErrCloneInProgress = errors.New("clone from snapshot is already in progress") ErrCloneInProgress = coreError.New("clone from snapshot is already in progress")
// ErrClonePending is returned when snapshot clone state is `pending`. // ErrClonePending is returned when snapshot clone state is `pending`.
ErrClonePending = errors.New("clone from snapshot is pending") ErrClonePending = coreError.New("clone from snapshot is pending")
// ErrInvalidClone is returned when the clone state is invalid. // ErrInvalidClone is returned when the clone state is invalid.
ErrInvalidClone = errors.New("invalid clone state") ErrInvalidClone = coreError.New("invalid clone state")
// ErrCloneFailed is returned when the clone state is failed. // ErrCloneFailed is returned when the clone state is failed.
ErrCloneFailed = errors.New("clone from snapshot failed") ErrCloneFailed = coreError.New("clone from snapshot failed")
// ErrInvalidVolID is returned when a CSI passed VolumeID is not conformant to any known volume ID // ErrInvalidVolID is returned when a CSI passed VolumeID is not conformant to any known volume ID
// formats. // formats.
ErrInvalidVolID = errors.New("invalid VolumeID") ErrInvalidVolID = coreError.New("invalid VolumeID")
// ErrNonStaticVolume is returned when a volume is detected as not being // ErrNonStaticVolume is returned when a volume is detected as not being
// statically provisioned. // statically provisioned.
ErrNonStaticVolume = errors.New("volume not static") ErrNonStaticVolume = coreError.New("volume not static")
// ErrSnapProtectionExist is returned when the snapshot is already protected. // ErrSnapProtectionExist is returned when the snapshot is already protected.
ErrSnapProtectionExist = errors.New("snapshot protection already exists") ErrSnapProtectionExist = coreError.New("snapshot protection already exists")
// ErrSnapNotFound is returned when snap name passed is not found in the list // ErrSnapNotFound is returned when snap name passed is not found in the list
// of snapshots for the given image. // of snapshots for the given image.
ErrSnapNotFound = errors.New("snapshot not found") ErrSnapNotFound = coreError.New("snapshot not found")
// ErrVolumeNotFound is returned when a subvolume is not found in CephFS. // ErrVolumeNotFound is returned when a subvolume is not found in CephFS.
ErrVolumeNotFound = errors.New("volume not found") ErrVolumeNotFound = coreError.New("volume not found")
// ErrInvalidCommand is returned when a command is not known to the cluster. // ErrInvalidCommand is returned when a command is not known to the cluster.
ErrInvalidCommand = errors.New("invalid command") ErrInvalidCommand = coreError.New("invalid command")
// ErrVolumeHasSnapshots is returned when a subvolume has snapshots. // ErrVolumeHasSnapshots is returned when a subvolume has snapshots.
ErrVolumeHasSnapshots = errors.New("volume has snapshots") ErrVolumeHasSnapshots = coreError.New("volume has snapshots")
) )

View File

@ -21,6 +21,7 @@ import (
"errors" "errors"
"fmt" "fmt"
cerrors "github.com/ceph/ceph-csi/internal/cephfs/errors"
"github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util"
"github.com/ceph/ceph-csi/internal/util/log" "github.com/ceph/ceph-csi/internal/util/log"
@ -86,7 +87,7 @@ func checkVolExists(ctx context.Context,
if sID != nil || pvID != nil { if sID != nil || pvID != nil {
cloneState, cloneStateErr := volOptions.getCloneState(ctx, volumeID(vid.FsSubvolName)) cloneState, cloneStateErr := volOptions.getCloneState(ctx, volumeID(vid.FsSubvolName))
if cloneStateErr != nil { if cloneStateErr != nil {
if errors.Is(cloneStateErr, ErrVolumeNotFound) { if errors.Is(cloneStateErr, cerrors.ErrVolumeNotFound) {
if pvID != nil { if pvID != nil {
err = cleanupCloneFromSubvolumeSnapshot( err = cleanupCloneFromSubvolumeSnapshot(
ctx, volumeID(pvID.FsSubvolName), ctx, volumeID(pvID.FsSubvolName),
@ -105,10 +106,10 @@ func checkVolExists(ctx context.Context,
return nil, err return nil, err
} }
if cloneState == cephFSCloneInprogress { if cloneState == cephFSCloneInprogress {
return nil, ErrCloneInProgress return nil, cerrors.ErrCloneInProgress
} }
if cloneState == cephFSClonePending { if cloneState == cephFSClonePending {
return nil, ErrClonePending return nil, cerrors.ErrClonePending
} }
if cloneState == cephFSCloneFailed { if cloneState == cephFSCloneFailed {
err = volOptions.purgeVolume(ctx, volumeID(vid.FsSubvolName), true) err = volOptions.purgeVolume(ctx, volumeID(vid.FsSubvolName), true)
@ -137,7 +138,7 @@ func checkVolExists(ctx context.Context,
} }
volOptions.RootPath, err = volOptions.getVolumeRootPathCeph(ctx, volumeID(vid.FsSubvolName)) volOptions.RootPath, err = volOptions.getVolumeRootPathCeph(ctx, volumeID(vid.FsSubvolName))
if err != nil { if err != nil {
if errors.Is(err, ErrVolumeNotFound) { if errors.Is(err, cerrors.ErrVolumeNotFound) {
// If the subvolume is not present, cleanup the stale snapshot // If the subvolume is not present, cleanup the stale snapshot
// created for clone. // created for clone.
if parentVolOpt != nil && pvID != nil { if parentVolOpt != nil && pvID != nil {
@ -379,7 +380,7 @@ func checkSnapExists(
sid.FsSnapshotName = snapData.ImageAttributes.ImageName sid.FsSnapshotName = snapData.ImageAttributes.ImageName
snapInfo, err := volOptions.getSnapshotInfo(ctx, volumeID(snapID), volumeID(parentSubVolName)) snapInfo, err := volOptions.getSnapshotInfo(ctx, volumeID(snapID), volumeID(parentSubVolName))
if err != nil { if err != nil {
if errors.Is(err, ErrSnapNotFound) { if errors.Is(err, cerrors.ErrSnapNotFound) {
err = j.UndoReservation(ctx, volOptions.MetadataPool, err = j.UndoReservation(ctx, volOptions.MetadataPool,
volOptions.MetadataPool, snapID, snap.RequestName) volOptions.MetadataPool, snapID, snap.RequestName)

View File

@ -23,6 +23,7 @@ import (
"os" "os"
"strings" "strings"
cerrors "github.com/ceph/ceph-csi/internal/cephfs/errors"
csicommon "github.com/ceph/ceph-csi/internal/csi-common" csicommon "github.com/ceph/ceph-csi/internal/csi-common"
"github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util"
"github.com/ceph/ceph-csi/internal/util/log" "github.com/ceph/ceph-csi/internal/util/log"
@ -90,14 +91,14 @@ func (ns *NodeServer) NodeStageVolume(
volOptions, _, err := newVolumeOptionsFromVolID(ctx, string(volID), req.GetVolumeContext(), req.GetSecrets()) volOptions, _, err := newVolumeOptionsFromVolID(ctx, string(volID), req.GetVolumeContext(), req.GetSecrets())
if err != nil { if err != nil {
if !errors.Is(err, ErrInvalidVolID) { if !errors.Is(err, cerrors.ErrInvalidVolID) {
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }
// gets mon IPs from the supplied cluster info // gets mon IPs from the supplied cluster info
volOptions, _, err = newVolumeOptionsFromStaticVolume(string(volID), req.GetVolumeContext()) volOptions, _, err = newVolumeOptionsFromStaticVolume(string(volID), req.GetVolumeContext())
if err != nil { if err != nil {
if !errors.Is(err, ErrNonStaticVolume) { if !errors.Is(err, cerrors.ErrNonStaticVolume) {
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }

View File

@ -21,6 +21,7 @@ import (
"errors" "errors"
"time" "time"
cerrors "github.com/ceph/ceph-csi/internal/cephfs/errors"
"github.com/ceph/ceph-csi/internal/util/log" "github.com/ceph/ceph-csi/internal/util/log"
"github.com/ceph/go-ceph/cephfs/admin" "github.com/ceph/go-ceph/cephfs/admin"
@ -105,7 +106,7 @@ func (vo *volumeOptions) getSnapshotInfo(ctx context.Context, snapID, volID volu
info, err := fsa.SubVolumeSnapshotInfo(vo.FsName, vo.SubvolumeGroup, string(volID), string(snapID)) info, err := fsa.SubVolumeSnapshotInfo(vo.FsName, vo.SubvolumeGroup, string(volID), string(snapID))
if err != nil { if err != nil {
if errors.Is(err, rados.ErrNotFound) { if errors.Is(err, rados.ErrNotFound) {
return snap, ErrSnapNotFound return snap, cerrors.ErrSnapNotFound
} }
log.ErrorLog( log.ErrorLog(
ctx, ctx,
@ -221,7 +222,7 @@ func (vo *volumeOptions) cloneSnapshot(
vo.FsName, vo.FsName,
err) err)
if errors.Is(err, rados.ErrNotFound) { if errors.Is(err, rados.ErrNotFound) {
return ErrVolumeNotFound return cerrors.ErrVolumeNotFound
} }
return err return err

View File

@ -23,6 +23,7 @@ import (
"path" "path"
"strings" "strings"
cerrors "github.com/ceph/ceph-csi/internal/cephfs/errors"
"github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util"
"github.com/ceph/ceph-csi/internal/util/log" "github.com/ceph/ceph-csi/internal/util/log"
@ -68,7 +69,7 @@ func (vo *volumeOptions) getVolumeRootPathCeph(ctx context.Context, volID volume
if err != nil { if err != nil {
log.ErrorLog(ctx, "failed to get the rootpath for the vol %s: %s", string(volID), err) log.ErrorLog(ctx, "failed to get the rootpath for the vol %s: %s", string(volID), err)
if errors.Is(err, rados.ErrNotFound) { if errors.Is(err, rados.ErrNotFound) {
return "", util.JoinErrors(ErrVolumeNotFound, err) return "", util.JoinErrors(cerrors.ErrVolumeNotFound, err)
} }
return "", err return "", err
@ -89,12 +90,12 @@ func (vo *volumeOptions) getSubVolumeInfo(ctx context.Context, volID volumeID) (
if err != nil { if err != nil {
log.ErrorLog(ctx, "failed to get subvolume info for the vol %s: %s", string(volID), err) log.ErrorLog(ctx, "failed to get subvolume info for the vol %s: %s", string(volID), err)
if errors.Is(err, rados.ErrNotFound) { if errors.Is(err, rados.ErrNotFound) {
return nil, ErrVolumeNotFound return nil, cerrors.ErrVolumeNotFound
} }
// In case the error is invalid command return error to the caller. // In case the error is invalid command return error to the caller.
var invalid fsAdmin.NotImplementedError var invalid fsAdmin.NotImplementedError
if errors.As(err, &invalid) { if errors.As(err, &invalid) {
return nil, ErrInvalidCommand return nil, cerrors.ErrInvalidCommand
} }
return nil, err return nil, err
@ -249,11 +250,11 @@ func (vo *volumeOptions) purgeVolume(ctx context.Context, volID volumeID, force
err = fsa.RemoveSubVolumeWithFlags(vo.FsName, vo.SubvolumeGroup, string(volID), opt) err = fsa.RemoveSubVolumeWithFlags(vo.FsName, vo.SubvolumeGroup, string(volID), opt)
if err != nil { if err != nil {
log.ErrorLog(ctx, "failed to purge subvolume %s in fs %s: %s", string(volID), vo.FsName, err) log.ErrorLog(ctx, "failed to purge subvolume %s in fs %s: %s", string(volID), vo.FsName, err)
if strings.Contains(err.Error(), volumeNotEmpty) { if strings.Contains(err.Error(), cerrors.VolumeNotEmpty) {
return util.JoinErrors(ErrVolumeHasSnapshots, err) return util.JoinErrors(cerrors.ErrVolumeHasSnapshots, err)
} }
if errors.Is(err, rados.ErrNotFound) { if errors.Is(err, rados.ErrNotFound) {
return util.JoinErrors(ErrVolumeNotFound, err) return util.JoinErrors(cerrors.ErrVolumeNotFound, err)
} }
return err return err

View File

@ -25,6 +25,7 @@ import (
"github.com/container-storage-interface/spec/lib/go/csi" "github.com/container-storage-interface/spec/lib/go/csi"
cerrors "github.com/ceph/ceph-csi/internal/cephfs/errors"
"github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util"
) )
@ -273,7 +274,7 @@ func newVolumeOptionsFromVolID(
if err != nil { if err != nil {
err = fmt.Errorf("error decoding volume ID (%s): %w", volID, err) err = fmt.Errorf("error decoding volume ID (%s): %w", volID, err)
return nil, nil, util.JoinErrors(ErrInvalidVolID, err) return nil, nil, util.JoinErrors(cerrors.ErrInvalidVolID, err)
} }
volOptions.ClusterID = vi.ClusterID volOptions.ClusterID = vi.ClusterID
vid.VolumeID = volID vid.VolumeID = volID
@ -360,7 +361,7 @@ func newVolumeOptionsFromVolID(
volOptions.Features = info.Features volOptions.Features = info.Features
} }
if errors.Is(err, ErrInvalidCommand) { if errors.Is(err, cerrors.ErrInvalidCommand) {
volOptions.RootPath, err = volOptions.getVolumeRootPathCeph(ctx, volumeID(vid.FsSubvolName)) volOptions.RootPath, err = volOptions.getVolumeRootPathCeph(ctx, volumeID(vid.FsSubvolName))
} }
@ -444,7 +445,7 @@ func newVolumeOptionsFromStaticVolume(
val, ok := options["staticVolume"] val, ok := options["staticVolume"]
if !ok { if !ok {
return nil, nil, ErrNonStaticVolume return nil, nil, cerrors.ErrNonStaticVolume
} }
if staticVol, err = strconv.ParseBool(val); err != nil { if staticVol, err = strconv.ParseBool(val); err != nil {
@ -452,7 +453,7 @@ func newVolumeOptionsFromStaticVolume(
} }
if !staticVol { if !staticVol {
return nil, nil, ErrNonStaticVolume return nil, nil, cerrors.ErrNonStaticVolume
} }
// Volume is static, and ProvisionVolume carries bool stating if it was provisioned, hence // Volume is static, and ProvisionVolume carries bool stating if it was provisioned, hence
@ -512,7 +513,7 @@ func newSnapshotOptionsFromID(
// Decode the snapID first, to detect pre-provisioned snapshot before other errors // Decode the snapID first, to detect pre-provisioned snapshot before other errors
err := vi.DecomposeCSIID(snapID) err := vi.DecomposeCSIID(snapID)
if err != nil { if err != nil {
return &volOptions, nil, &sid, ErrInvalidVolID return &volOptions, nil, &sid, cerrors.ErrInvalidVolID
} }
volOptions.ClusterID = vi.ClusterID volOptions.ClusterID = vi.ClusterID
sid.SnapshotID = snapID sid.SnapshotID = snapID

View File

@ -125,7 +125,12 @@ func initAWSMetadataKMS(args ProviderInitArgs) (EncryptionKMS, error) {
} }
func (kms *AWSMetadataKMS) getSecrets() (map[string]interface{}, error) { func (kms *AWSMetadataKMS) getSecrets() (map[string]interface{}, error) {
c := k8s.NewK8sClient() c, err := k8s.NewK8sClient()
if err != nil {
return nil, fmt.Errorf("failed to connect to Kubernetes to "+
"get Secret %s/%s: %w", kms.namespace, kms.secretName, err)
}
secret, err := c.CoreV1().Secrets(kms.namespace).Get(context.TODO(), secret, err := c.CoreV1().Secrets(kms.namespace).Get(context.TODO(),
kms.secretName, metav1.GetOptions{}) kms.secretName, metav1.GetOptions{})
if err != nil { if err != nil {

View File

@ -154,7 +154,12 @@ func getKMSConfigMap() (map[string]interface{}, error) {
} }
cmName := getKMSConfigMapName() cmName := getKMSConfigMapName()
c := k8s.NewK8sClient() c, err := k8s.NewK8sClient()
if err != nil {
return nil, fmt.Errorf("can not get ConfigMap %q, failed to "+
"connect to Kubernetes: %w", cmName, err)
}
cm, err := c.CoreV1().ConfigMaps(ns).Get(context.Background(), cm, err := c.CoreV1().ConfigMaps(ns).Get(context.Background(),
cmName, metav1.GetOptions{}) cmName, metav1.GetOptions{})
if err != nil { if err != nil {

View File

@ -159,7 +159,12 @@ func (kms SecretsMetadataKMS) fetchEncryptionPassphrase(
secretNamespace = defaultNamespace secretNamespace = defaultNamespace
} }
c := k8s.NewK8sClient() c, err := k8s.NewK8sClient()
if err != nil {
return "", fmt.Errorf("can not get Secret %s/%s, failed to "+
"connect to Kubernetes: %w", secretNamespace, secretName, err)
}
secret, err := c.CoreV1().Secrets(secretNamespace).Get(context.TODO(), secret, err := c.CoreV1().Secrets(secretNamespace).Get(context.TODO(),
secretName, metav1.GetOptions{}) secretName, metav1.GetOptions{})
if err != nil { if err != nil {

View File

@ -260,7 +260,12 @@ func (kms *VaultTenantSA) setServiceAccountName(config map[string]interface{}) e
// getServiceAccount returns the Tenants ServiceAccount with the name // getServiceAccount returns the Tenants ServiceAccount with the name
// configured in the VaultTenantSA. // configured in the VaultTenantSA.
func (kms *VaultTenantSA) getServiceAccount() (*corev1.ServiceAccount, error) { func (kms *VaultTenantSA) getServiceAccount() (*corev1.ServiceAccount, error) {
c := kms.getK8sClient() c, err := kms.getK8sClient()
if err != nil {
return nil, fmt.Errorf("can not get ServiceAccount %s/%s, "+
"failed to connect to Kubernetes: %w", kms.Tenant, kms.tenantSAName, err)
}
sa, err := c.CoreV1().ServiceAccounts(kms.Tenant).Get(context.TODO(), sa, err := c.CoreV1().ServiceAccounts(kms.Tenant).Get(context.TODO(),
kms.tenantSAName, metav1.GetOptions{}) kms.tenantSAName, metav1.GetOptions{})
if err != nil { if err != nil {
@ -279,7 +284,13 @@ func (kms *VaultTenantSA) getToken() (string, error) {
return "", err return "", err
} }
c := kms.getK8sClient() c, err := kms.getK8sClient()
if err != nil {
return "", fmt.Errorf("can not get ServiceAccount %s/%s, failed "+
"to connect to Kubernetes: %w", kms.Tenant,
kms.tenantSAName, err)
}
for _, secretRef := range sa.Secrets { for _, secretRef := range sa.Secrets {
secret, err := c.CoreV1().Secrets(kms.Tenant).Get(context.TODO(), secretRef.Name, metav1.GetOptions{}) secret, err := c.CoreV1().Secrets(kms.Tenant).Get(context.TODO(), secretRef.Name, metav1.GetOptions{})
if err != nil { if err != nil {

View File

@ -438,12 +438,16 @@ func (vtc *vaultTenantConnection) initCertificates(config map[string]interface{}
return nil return nil
} }
func (vtc *vaultTenantConnection) getK8sClient() *kubernetes.Clientset { func (vtc *vaultTenantConnection) getK8sClient() (*kubernetes.Clientset, error) {
if vtc.client == nil { if vtc.client == nil {
vtc.client = k8s.NewK8sClient() client, err := k8s.NewK8sClient()
if err != nil {
return nil, err
}
vtc.client = client
} }
return vtc.client return vtc.client, nil
} }
// FetchDEK returns passphrase from Vault. The passphrase is stored in a // FetchDEK returns passphrase from Vault. The passphrase is stored in a
@ -493,7 +497,11 @@ func (vtc *vaultTenantConnection) RemoveDEK(key string) error {
} }
func (kms *VaultTokensKMS) getToken() (string, error) { func (kms *VaultTokensKMS) getToken() (string, error) {
c := kms.getK8sClient() c, err := kms.getK8sClient()
if err != nil {
return "", err
}
secret, err := c.CoreV1().Secrets(kms.Tenant).Get(context.TODO(), kms.TokenName, metav1.GetOptions{}) secret, err := c.CoreV1().Secrets(kms.Tenant).Get(context.TODO(), kms.TokenName, metav1.GetOptions{})
if err != nil { if err != nil {
return "", err return "", err
@ -508,7 +516,11 @@ func (kms *VaultTokensKMS) getToken() (string, error) {
} }
func (vtc *vaultTenantConnection) getCertificate(tenant, secretName, key string) (string, error) { func (vtc *vaultTenantConnection) getCertificate(tenant, secretName, key string) (string, error) {
c := vtc.getK8sClient() c, err := vtc.getK8sClient()
if err != nil {
return "", err
}
secret, err := c.CoreV1().Secrets(tenant).Get(context.TODO(), secretName, metav1.GetOptions{}) secret, err := c.CoreV1().Secrets(tenant).Get(context.TODO(), secretName, metav1.GetOptions{})
if err != nil { if err != nil {
return "", err return "", err
@ -551,7 +563,11 @@ func (vtc *vaultTenantConnection) parseTenantConfig() (map[string]interface{}, e
} }
// fetch the ConfigMap from the tenants namespace // fetch the ConfigMap from the tenants namespace
c := vtc.getK8sClient() c, err := vtc.getK8sClient()
if err != nil {
return nil, err
}
cm, err := c.CoreV1().ConfigMaps(vtc.Tenant).Get(context.TODO(), cm, err := c.CoreV1().ConfigMaps(vtc.Tenant).Get(context.TODO(),
vtc.ConfigName, metav1.GetOptions{}) vtc.ConfigName, metav1.GetOptions{})
if apierrs.IsNotFound(err) { if apierrs.IsNotFound(err) {

View File

@ -743,9 +743,56 @@ func checkContentSource(
return nil, nil, status.Errorf(codes.InvalidArgument, "not a proper volume source") return nil, nil, status.Errorf(codes.InvalidArgument, "not a proper volume source")
} }
// checkErrAndUndoReserve work on error from genVolFromVolID() and undo omap reserve.
// Even-though volumeID is part of rbdVolume struct we take it as an arg here, the main reason
// being, the volume id is getting filled from `genVolFromVolID->generateVolumeFromVolumeID` call path,
// and this function is operating on the error case/scenario of above call chain, so we can not rely
// on the 'rbdvol->rbdimage->voldID' field.
func (cs *ControllerServer) checkErrAndUndoReserve(
ctx context.Context,
err error,
volumeID string,
rbdVol *rbdVolume, cr *util.Credentials) (*csi.DeleteVolumeResponse, error) {
if errors.Is(err, util.ErrPoolNotFound) {
log.WarningLog(ctx, "failed to get backend volume for %s: %v", volumeID, err)
return &csi.DeleteVolumeResponse{}, nil
}
// if error is ErrKeyNotFound, then a previous attempt at deletion was complete
// or partially complete (image and imageOMap are garbage collected already), hence return
// success as deletion is complete
if errors.Is(err, util.ErrKeyNotFound) {
log.WarningLog(ctx, "failed to volume options for %s: %v", volumeID, err)
return &csi.DeleteVolumeResponse{}, nil
}
// All errors other than ErrImageNotFound should return an error back to the caller
if !errors.Is(err, ErrImageNotFound) {
return nil, status.Error(codes.Internal, err.Error())
}
// If error is ErrImageNotFound then we failed to find the image, but found the imageOMap
// to lead us to the image, hence the imageOMap needs to be garbage collected, by calling
// unreserve for the same
if acquired := cs.VolumeLocks.TryAcquire(rbdVol.RequestName); !acquired {
log.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, rbdVol.RequestName)
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, rbdVol.RequestName)
}
defer cs.VolumeLocks.Release(rbdVol.RequestName)
if err = undoVolReservation(ctx, rbdVol, cr); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &csi.DeleteVolumeResponse{}, nil
}
// DeleteVolume deletes the volume in backend and removes the volume metadata // DeleteVolume deletes the volume in backend and removes the volume metadata
// from store // from store.
// TODO: make this function less complex.
func (cs *ControllerServer) DeleteVolume( func (cs *ControllerServer) DeleteVolume(
ctx context.Context, ctx context.Context,
req *csi.DeleteVolumeRequest) (*csi.DeleteVolumeResponse, error) { req *csi.DeleteVolumeRequest) (*csi.DeleteVolumeResponse, error) {
@ -786,41 +833,7 @@ func (cs *ControllerServer) DeleteVolume(
rbdVol, err := genVolFromVolID(ctx, volumeID, cr, req.GetSecrets()) rbdVol, err := genVolFromVolID(ctx, volumeID, cr, req.GetSecrets())
defer rbdVol.Destroy() defer rbdVol.Destroy()
if err != nil { if err != nil {
if errors.Is(err, util.ErrPoolNotFound) { return cs.checkErrAndUndoReserve(ctx, err, volumeID, rbdVol, cr)
log.WarningLog(ctx, "failed to get backend volume for %s: %v", volumeID, err)
return &csi.DeleteVolumeResponse{}, nil
}
// if error is ErrKeyNotFound, then a previous attempt at deletion was complete
// or partially complete (image and imageOMap are garbage collected already), hence return
// success as deletion is complete
if errors.Is(err, util.ErrKeyNotFound) {
log.WarningLog(ctx, "Failed to volume options for %s: %v", volumeID, err)
return &csi.DeleteVolumeResponse{}, nil
}
// All errors other than ErrImageNotFound should return an error back to the caller
if !errors.Is(err, ErrImageNotFound) {
return nil, status.Error(codes.Internal, err.Error())
}
// If error is ErrImageNotFound then we failed to find the image, but found the imageOMap
// to lead us to the image, hence the imageOMap needs to be garbage collected, by calling
// unreserve for the same
if acquired := cs.VolumeLocks.TryAcquire(rbdVol.RequestName); !acquired {
log.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, rbdVol.RequestName)
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, rbdVol.RequestName)
}
defer cs.VolumeLocks.Release(rbdVol.RequestName)
if err = undoVolReservation(ctx, rbdVol, cr); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &csi.DeleteVolumeResponse{}, nil
} }
// lock out parallel create requests against the same volume name as we // lock out parallel create requests against the same volume name as we

View File

@ -149,28 +149,14 @@ func healerStageTransaction(ctx context.Context, cr *util.Credentials, volOps *r
return nil return nil
} }
// NodeStageVolume mounts the volume to a staging path on the node. // populateRbdVol update the fields in rbdVolume struct based on the request it received.
// Implementation notes: func populateRbdVol(
// - stagingTargetPath is the directory passed in the request where the volume needs to be staged
// - We stage the volume into a directory, named after the VolumeID inside stagingTargetPath if
// it is a file system
// - We stage the volume into a file, named after the VolumeID inside stagingTargetPath if it is
// a block volume
// - Order of operation execution: (useful for defer stacking and when Unstaging to ensure steps
// are done in reverse, this is done in undoStagingTransaction)
// - Stash image metadata under staging path
// - Map the image (creates a device)
// - Create the staging file/directory under staging path
// - Stage the device (mount the device mapped for image)
// TODO: make this function less complex.
// nolint:gocyclo,cyclop // reduce complexity
func (ns *NodeServer) NodeStageVolume(
ctx context.Context, ctx context.Context,
req *csi.NodeStageVolumeRequest) (*csi.NodeStageVolumeResponse, error) { req *csi.NodeStageVolumeRequest,
if err := util.ValidateNodeStageVolumeRequest(req); err != nil { cr *util.Credentials) (*rbdVolume, error) {
return nil, err var err error
} var j *journal.Connection
volID := req.GetVolumeId()
isBlock := req.GetVolumeCapability().GetBlock() != nil isBlock := req.GetVolumeCapability().GetBlock() != nil
disableInUseChecks := false disableInUseChecks := false
// MULTI_NODE_MULTI_WRITER is supported by default for Block access type volumes // MULTI_NODE_MULTI_WRITER is supported by default for Block access type volumes
@ -192,6 +178,77 @@ func (ns *NodeServer) NodeStageVolume(
disableInUseChecks = true disableInUseChecks = true
} }
rv, err := genVolFromVolumeOptions(ctx, req.GetVolumeContext(), req.GetSecrets(), disableInUseChecks)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
rv.ThickProvision = isThickProvisionRequest(req.GetVolumeContext())
isStaticVol := isStaticVolume(req.GetVolumeContext())
// get rbd image name from the volume journal
// for static volumes, the image name is actually the volume ID itself
if isStaticVol {
rv.RbdImageName = volID
} else {
var vi util.CSIIdentifier
var imageAttributes *journal.ImageAttributes
err = vi.DecomposeCSIID(volID)
if err != nil {
err = fmt.Errorf("error decoding volume ID (%s): %w", volID, err)
return nil, status.Error(codes.Internal, err.Error())
}
j, err = volJournal.Connect(rv.Monitors, rv.RadosNamespace, cr)
if err != nil {
log.ErrorLog(ctx, "failed to establish cluster connection: %v", err)
return nil, status.Error(codes.Internal, err.Error())
}
defer j.Destroy()
imageAttributes, err = j.GetImageAttributes(
ctx, rv.Pool, vi.ObjectUUID, false)
if err != nil {
err = fmt.Errorf("error fetching image attributes for volume ID (%s): %w", volID, err)
return nil, status.Error(codes.Internal, err.Error())
}
rv.RbdImageName = imageAttributes.ImageName
}
rv.VolID = volID
rv.MapOptions = req.GetVolumeContext()["mapOptions"]
rv.UnmapOptions = req.GetVolumeContext()["unmapOptions"]
rv.Mounter = req.GetVolumeContext()["mounter"]
rv.LogDir = req.GetVolumeContext()["cephLogDir"]
if rv.LogDir == "" {
rv.LogDir = defaultLogDir
}
return rv, err
}
// NodeStageVolume mounts the volume to a staging path on the node.
// Implementation notes:
// - stagingTargetPath is the directory passed in the request where the volume needs to be staged
// - We stage the volume into a directory, named after the VolumeID inside stagingTargetPath if
// it is a file system
// - We stage the volume into a file, named after the VolumeID inside stagingTargetPath if it is
// a block volume
// - Order of operation execution: (useful for defer stacking and when Unstaging to ensure steps
// are done in reverse, this is done in undoStagingTransaction)
// - Stash image metadata under staging path
// - Map the image (creates a device)
// - Create the staging file/directory under staging path
// - Stage the device (mount the device mapped for image)
func (ns *NodeServer) NodeStageVolume(
ctx context.Context,
req *csi.NodeStageVolumeRequest) (*csi.NodeStageVolumeResponse, error) {
if err := util.ValidateNodeStageVolumeRequest(req); err != nil {
return nil, err
}
volID := req.GetVolumeId() volID := req.GetVolumeId()
cr, err := util.NewUserCredentials(req.GetSecrets()) cr, err := util.NewUserCredentials(req.GetSecrets())
@ -232,64 +289,21 @@ func (ns *NodeServer) NodeStageVolume(
return nil, status.Error(codes.InvalidArgument, "missing required parameter imageFeatures") return nil, status.Error(codes.InvalidArgument, "missing required parameter imageFeatures")
} }
volOptions, err := genVolFromVolumeOptions(ctx, req.GetVolumeContext(), req.GetSecrets(), disableInUseChecks) rv, err := populateRbdVol(ctx, req, cr)
if err != nil { if err != nil {
return nil, status.Error(codes.Internal, err.Error()) return nil, err
} }
volOptions.ThickProvision = isThickProvisionRequest(req.GetVolumeContext()) err = rv.Connect(cr)
// get rbd image name from the volume journal
// for static volumes, the image name is actually the volume ID itself
if isStaticVol {
volOptions.RbdImageName = volID
} else {
var vi util.CSIIdentifier
var imageAttributes *journal.ImageAttributes
err = vi.DecomposeCSIID(volID)
if err != nil {
err = fmt.Errorf("error decoding volume ID (%s): %w", volID, err)
return nil, status.Error(codes.Internal, err.Error())
}
j, connErr := volJournal.Connect(volOptions.Monitors, volOptions.RadosNamespace, cr)
if connErr != nil {
log.ErrorLog(ctx, "failed to establish cluster connection: %v", connErr)
return nil, status.Error(codes.Internal, connErr.Error())
}
defer j.Destroy()
imageAttributes, err = j.GetImageAttributes(
ctx, volOptions.Pool, vi.ObjectUUID, false)
if err != nil {
err = fmt.Errorf("error fetching image attributes for volume ID (%s): %w", volID, err)
return nil, status.Error(codes.Internal, err.Error())
}
volOptions.RbdImageName = imageAttributes.ImageName
}
volOptions.VolID = volID
volOptions.MapOptions = req.GetVolumeContext()["mapOptions"]
volOptions.UnmapOptions = req.GetVolumeContext()["unmapOptions"]
volOptions.Mounter = req.GetVolumeContext()["mounter"]
volOptions.LogDir = req.GetVolumeContext()["cephLogDir"]
if volOptions.LogDir == "" {
volOptions.LogDir = defaultLogDir
}
err = volOptions.Connect(cr)
if err != nil { if err != nil {
log.ErrorLog(ctx, "failed to connect to volume %s: %v", volOptions, err) log.ErrorLog(ctx, "failed to connect to volume %s: %v", rv, err)
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }
defer volOptions.Destroy() defer rv.Destroy()
if isHealer { if isHealer {
err = healerStageTransaction(ctx, cr, volOptions, stagingParentPath) err = healerStageTransaction(ctx, cr, rv, stagingParentPath)
if err != nil { if err != nil {
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }
@ -300,19 +314,19 @@ func (ns *NodeServer) NodeStageVolume(
transaction := stageTransaction{} transaction := stageTransaction{}
// Stash image details prior to mapping the image (useful during Unstage as it has no // Stash image details prior to mapping the image (useful during Unstage as it has no
// voloptions passed to the RPC as per the CSI spec) // voloptions passed to the RPC as per the CSI spec)
err = stashRBDImageMetadata(volOptions, stagingParentPath) err = stashRBDImageMetadata(rv, stagingParentPath)
if err != nil { if err != nil {
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }
defer func() { defer func() {
if err != nil { if err != nil {
ns.undoStagingTransaction(ctx, req, transaction, volOptions) ns.undoStagingTransaction(ctx, req, transaction, rv)
} }
}() }()
// perform the actual staging and if this fails, have undoStagingTransaction // perform the actual staging and if this fails, have undoStagingTransaction
// cleans up for us // cleans up for us
transaction, err = ns.stageTransaction(ctx, req, volOptions, isStaticVol) transaction, err = ns.stageTransaction(ctx, req, rv, isStaticVol)
if err != nil { if err != nil {
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }

View File

@ -243,19 +243,11 @@ func attachRBDImage(ctx context.Context, volOptions *rbdVolume, device string, c
return devicePath, err return devicePath, err
} }
func appendDeviceTypeAndOptions(cmdArgs []string, isNbd, isThick bool, userOptions string) []string { func appendNbdDeviceTypeAndOptions(cmdArgs []string, isThick bool, userOptions string) []string {
accessType := accessTypeKRbd cmdArgs = append(cmdArgs, "--device-type", accessTypeNbd)
if isNbd {
accessType = accessTypeNbd
}
cmdArgs = append(cmdArgs, "--device-type", accessType) isUnmap := CheckSliceContains(cmdArgs, "unmap")
if !isNbd { if !isUnmap {
// Enable mapping and unmapping images from a non-initial network
// namespace (e.g. for Multus CNI). The network namespace must be
// owned by the initial user namespace.
cmdArgs = append(cmdArgs, "--options", "noudev")
} else {
if !strings.Contains(userOptions, useNbdNetlink) { if !strings.Contains(userOptions, useNbdNetlink) {
cmdArgs = append(cmdArgs, "--options", useNbdNetlink) cmdArgs = append(cmdArgs, "--options", useNbdNetlink)
} }
@ -265,12 +257,40 @@ func appendDeviceTypeAndOptions(cmdArgs []string, isNbd, isThick bool, userOptio
if !strings.Contains(userOptions, setNbdIOTimeout) { if !strings.Contains(userOptions, setNbdIOTimeout) {
cmdArgs = append(cmdArgs, "--options", fmt.Sprintf("%s=%d", setNbdIOTimeout, defaultNbdIOTimeout)) cmdArgs = append(cmdArgs, "--options", fmt.Sprintf("%s=%d", setNbdIOTimeout, defaultNbdIOTimeout))
} }
if isThick {
// When an image is thick-provisioned, any discard/unmap/trim
// requests should not free extents.
cmdArgs = append(cmdArgs, "--options", "notrim")
}
} }
if isThick {
// When an image is thick-provisioned, any discard/unmap/trim if userOptions != "" {
// requests should not free extents. // userOptions is appended after, possibly overriding the above
cmdArgs = append(cmdArgs, "--options", "notrim") // default options.
cmdArgs = append(cmdArgs, "--options", userOptions)
} }
return cmdArgs
}
func appendKRbdDeviceTypeAndOptions(cmdArgs []string, isThick bool, userOptions string) []string {
cmdArgs = append(cmdArgs, "--device-type", accessTypeKRbd)
isUnmap := CheckSliceContains(cmdArgs, "unmap")
if !isUnmap {
if isThick {
// When an image is thick-provisioned, any discard/unmap/trim
// requests should not free extents.
cmdArgs = append(cmdArgs, "--options", "notrim")
}
}
// Enable mapping and unmapping images from a non-initial network
// namespace (e.g. for Multus CNI). The network namespace must be
// owned by the initial user namespace.
cmdArgs = append(cmdArgs, "--options", "noudev")
if userOptions != "" { if userOptions != "" {
// userOptions is appended after, possibly overriding the above // userOptions is appended after, possibly overriding the above
// default options. // default options.
@ -338,7 +358,11 @@ func createPath(ctx context.Context, volOpt *rbdVolume, device string, cr *util.
mapArgs = appendRbdNbdCliOptions(mapArgs, volOpt.MapOptions) mapArgs = appendRbdNbdCliOptions(mapArgs, volOpt.MapOptions)
} else { } else {
mapArgs = append(mapArgs, "map", imagePath) mapArgs = append(mapArgs, "map", imagePath)
mapArgs = appendDeviceTypeAndOptions(mapArgs, isNbd, isThick, volOpt.MapOptions) if isNbd {
mapArgs = appendNbdDeviceTypeAndOptions(mapArgs, isThick, volOpt.MapOptions)
} else {
mapArgs = appendKRbdDeviceTypeAndOptions(mapArgs, isThick, volOpt.MapOptions)
}
} }
if volOpt.readOnly { if volOpt.readOnly {
@ -443,7 +467,11 @@ func detachRBDImageOrDeviceSpec(
} }
unmapArgs := []string{"unmap", dArgs.imageOrDeviceSpec} unmapArgs := []string{"unmap", dArgs.imageOrDeviceSpec}
unmapArgs = appendDeviceTypeAndOptions(unmapArgs, dArgs.isNbd, false, dArgs.unmapOptions) if dArgs.isNbd {
unmapArgs = appendNbdDeviceTypeAndOptions(unmapArgs, false, dArgs.unmapOptions)
} else {
unmapArgs = appendKRbdDeviceTypeAndOptions(unmapArgs, false, dArgs.unmapOptions)
}
_, stderr, err := util.ExecCommand(ctx, rbd, unmapArgs...) _, stderr, err := util.ExecCommand(ctx, rbd, unmapArgs...)
if err != nil { if err != nil {

View File

@ -129,7 +129,13 @@ func callNodeStageVolume(ns *NodeServer, c *k8s.Clientset, pv *v1.PersistentVolu
// runVolumeHealer heal the volumes attached on a node. // runVolumeHealer heal the volumes attached on a node.
func runVolumeHealer(ns *NodeServer, conf *util.Config) error { func runVolumeHealer(ns *NodeServer, conf *util.Config) error {
c := kubeclient.NewK8sClient() c, err := kubeclient.NewK8sClient()
if err != nil {
log.ErrorLogMsg("failed to connect to Kubernetes: %v", err)
return err
}
val, err := c.StorageV1().VolumeAttachments().List(context.TODO(), metav1.ListOptions{}) val, err := c.StorageV1().VolumeAttachments().List(context.TODO(), metav1.ListOptions{})
if err != nil { if err != nil {
log.ErrorLogMsg("list volumeAttachments failed, err: %v", err) log.ErrorLogMsg("list volumeAttachments failed, err: %v", err)

View File

@ -1064,7 +1064,11 @@ func genVolFromVolID(
// be the same in the PV.Spec.CSI.VolumeHandle. Check the PV annotation for // be the same in the PV.Spec.CSI.VolumeHandle. Check the PV annotation for
// the new volumeHandle. If the new volumeHandle is found, generate the RBD // the new volumeHandle. If the new volumeHandle is found, generate the RBD
// volume structure from the new volumeHandle. // volume structure from the new volumeHandle.
c := k8s.NewK8sClient() c, cErr := k8s.NewK8sClient()
if cErr != nil {
return vol, cErr
}
listOpt := metav1.ListOptions{ listOpt := metav1.ListOptions{
LabelSelector: PVReplicatedLabelKey, LabelSelector: PVReplicatedLabelKey,
} }
@ -2007,3 +2011,14 @@ func getCephClientLogFileName(id, logDir, prefix string) string {
return fmt.Sprintf("%s/%s-%s.log", logDir, prefix, id) return fmt.Sprintf("%s/%s-%s.log", logDir, prefix, id)
} }
// CheckSliceContains checks the slice for string.
func CheckSliceContains(options []string, opt string) bool {
for _, o := range options {
if o == opt {
return true
}
}
return false
}

View File

@ -324,8 +324,7 @@ func (rs *ReplicationServer) DisableVolumeReplication(ctx context.Context,
case librbd.MirrorImageEnabled: case librbd.MirrorImageEnabled:
return disableVolumeReplication(rbdVol, mirroringInfo, force) return disableVolumeReplication(rbdVol, mirroringInfo, force)
default: default:
// TODO: use string instead of int for returning valid error message return nil, status.Errorf(codes.InvalidArgument, "image is in %s Mode", mirroringInfo.State)
return nil, status.Errorf(codes.InvalidArgument, "image is in %d Mode", mirroringInfo.State)
} }
return &replication.DisableVolumeReplicationResponse{}, nil return &replication.DisableVolumeReplicationResponse{}, nil

View File

@ -50,11 +50,16 @@ func createCephConfigRoot() error {
// WriteCephConfig writes out a basic ceph.conf file, making it easy to use // WriteCephConfig writes out a basic ceph.conf file, making it easy to use
// ceph related CLIs. // ceph related CLIs.
func WriteCephConfig() error { func WriteCephConfig() error {
if err := createCephConfigRoot(); err != nil { var err error
if err = createCephConfigRoot(); err != nil {
return err return err
} }
err := ioutil.WriteFile(CephConfigPath, cephConfig, 0o600) // create config file if it does not exist to support backward compatibility
if _, err = os.Stat(CephConfigPath); os.IsNotExist(err) {
err = ioutil.WriteFile(CephConfigPath, cephConfig, 0o600)
}
if err != nil { if err != nil {
return err return err
} }
@ -71,7 +76,11 @@ if any ceph commands fails it will log below error message
*/ */
// createKeyRingFile creates the keyring files to fix above error message logging. // createKeyRingFile creates the keyring files to fix above error message logging.
func createKeyRingFile() error { func createKeyRingFile() error {
_, err := os.Create(keyRing) var err error
// create keyring file if it does not exist to support backward compatibility
if _, err = os.Stat(keyRing); os.IsNotExist(err) {
_, err = os.Create(keyRing)
}
return err return err
} }

View File

@ -17,35 +17,34 @@ limitations under the License.
package k8s package k8s
import ( import (
"fmt"
"os" "os"
"github.com/ceph/ceph-csi/internal/util/log"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
) )
// NewK8sClient create kubernetes client. // NewK8sClient create kubernetes client.
func NewK8sClient() *kubernetes.Clientset { func NewK8sClient() (*kubernetes.Clientset, error) {
var cfg *rest.Config var cfg *rest.Config
var err error var err error
cPath := os.Getenv("KUBERNETES_CONFIG_PATH") cPath := os.Getenv("KUBERNETES_CONFIG_PATH")
if cPath != "" { if cPath != "" {
cfg, err = clientcmd.BuildConfigFromFlags("", cPath) cfg, err = clientcmd.BuildConfigFromFlags("", cPath)
if err != nil { if err != nil {
log.FatalLogMsg("Failed to get cluster config with error: %v\n", err) return nil, fmt.Errorf("failed to get cluster config from %q: %w", cPath, err)
} }
} else { } else {
cfg, err = rest.InClusterConfig() cfg, err = rest.InClusterConfig()
if err != nil { if err != nil {
log.FatalLogMsg("Failed to get cluster config with error: %v\n", err) return nil, fmt.Errorf("failed to get cluster config: %w", err)
} }
} }
client, err := kubernetes.NewForConfig(cfg) client, err := kubernetes.NewForConfig(cfg)
if err != nil { if err != nil {
log.FatalLogMsg("Failed to create client with error: %v\n", err) return nil, fmt.Errorf("failed to create client: %w", err)
} }
return client return client, nil
} }

View File

@ -35,7 +35,12 @@ const (
) )
func k8sGetNodeLabels(nodeName string) (map[string]string, error) { func k8sGetNodeLabels(nodeName string) (map[string]string, error) {
client := k8s.NewK8sClient() client, err := k8s.NewK8sClient()
if err != nil {
return nil, fmt.Errorf("can not get node %q information, failed "+
"to connect to Kubernetes: %w", nodeName, err)
}
node, err := client.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) node, err := client.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{})
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get node %q information: %w", nodeName, err) return nil, fmt.Errorf("failed to get node %q information: %w", nodeName, err)

View File

@ -173,9 +173,11 @@ install_cephcsi_helm_charts() {
check_deployment_status app=ceph-csi-cephfs ${NAMESPACE} check_deployment_status app=ceph-csi-cephfs ${NAMESPACE}
check_daemonset_status app=ceph-csi-cephfs ${NAMESPACE} check_daemonset_status app=ceph-csi-cephfs ${NAMESPACE}
# deleting configmap as a workaround to avoid configmap already present # deleting configmaps as a workaround to avoid configmap already present
# issue when installing ceph-csi-rbd # issue when installing ceph-csi-rbd
kubectl_retry delete cm ceph-csi-config --namespace ${NAMESPACE} kubectl_retry delete cm ceph-csi-config --namespace ${NAMESPACE}
kubectl_retry delete cm ceph-config --namespace ${NAMESPACE}
# shellcheck disable=SC2086 # shellcheck disable=SC2086
"${HELM}" install --namespace ${NAMESPACE} --set provisioner.fullnameOverride=csi-rbdplugin-provisioner --set nodeplugin.fullnameOverride=csi-rbdplugin --set configMapName=ceph-csi-config --set provisioner.podSecurityPolicy.enabled=true --set nodeplugin.podSecurityPolicy.enabled=true --set provisioner.replicaCount=1 ${SET_SC_TEMPLATE_VALUES} ${RBD_SECRET_TEMPLATE_VALUES} ${RBD_CHART_NAME} "${SCRIPT_DIR}"/../charts/ceph-csi-rbd --set topology.enabled=true --set topology.domainLabels="{${NODE_LABEL_REGION},${NODE_LABEL_ZONE}}" --set provisioner.maxSnapshotsOnImage=3 --set provisioner.minSnapshotsOnImage=2 "${HELM}" install --namespace ${NAMESPACE} --set provisioner.fullnameOverride=csi-rbdplugin-provisioner --set nodeplugin.fullnameOverride=csi-rbdplugin --set configMapName=ceph-csi-config --set provisioner.podSecurityPolicy.enabled=true --set nodeplugin.podSecurityPolicy.enabled=true --set provisioner.replicaCount=1 ${SET_SC_TEMPLATE_VALUES} ${RBD_SECRET_TEMPLATE_VALUES} ${RBD_CHART_NAME} "${SCRIPT_DIR}"/../charts/ceph-csi-rbd --set topology.enabled=true --set topology.domainLabels="{${NODE_LABEL_REGION},${NODE_LABEL_ZONE}}" --set provisioner.maxSnapshotsOnImage=3 --set provisioner.minSnapshotsOnImage=2

View File

@ -154,6 +154,8 @@ MINIKUBE_WAIT=${MINIKUBE_WAIT:-"all"}
CPUS=${CPUS:-"$(nproc)"} CPUS=${CPUS:-"$(nproc)"}
VM_DRIVER=${VM_DRIVER:-"virtualbox"} VM_DRIVER=${VM_DRIVER:-"virtualbox"}
CNI=${CNI:-"bridge"} CNI=${CNI:-"bridge"}
NUM_DISKS=${NUM_DISKS:-"1"}
DISK_SIZE=${DISK_SIZE:-"32g"}
#configure image repo #configure image repo
CEPHCSI_IMAGE_REPO=${CEPHCSI_IMAGE_REPO:-"quay.io/cephcsi"} CEPHCSI_IMAGE_REPO=${CEPHCSI_IMAGE_REPO:-"quay.io/cephcsi"}
K8S_IMAGE_REPO=${K8S_IMAGE_REPO:-"k8s.gcr.io/sig-storage"} K8S_IMAGE_REPO=${K8S_IMAGE_REPO:-"k8s.gcr.io/sig-storage"}
@ -162,6 +164,14 @@ if [[ "${VM_DRIVER}" == "kvm2" ]]; then
# use vda1 instead of sda1 when running with the libvirt driver # use vda1 instead of sda1 when running with the libvirt driver
DISK="vda1" DISK="vda1"
fi fi
if [[ "${VM_DRIVER}" == "kvm2" ]] || [[ "${VM_DRIVER}" == "hyperkit" ]]; then
# adding extra disks is only supported on kvm2 and hyperkit
DISK_CONFIG=${DISK_CONFIG:-" --extra-disks=${NUM_DISKS} --disk-size=${DISK_SIZE} "}
else
DISK_CONFIG=""
fi
#configure csi sidecar version #configure csi sidecar version
CSI_ATTACHER_VERSION=${CSI_ATTACHER_VERSION:-"v3.2.1"} CSI_ATTACHER_VERSION=${CSI_ATTACHER_VERSION:-"v3.2.1"}
CSI_SNAPSHOTTER_VERSION=${CSI_SNAPSHOTTER_VERSION:-"v4.1.1"} CSI_SNAPSHOTTER_VERSION=${CSI_SNAPSHOTTER_VERSION:-"v4.1.1"}
@ -216,16 +226,16 @@ up)
if minikube_supports_psp; then if minikube_supports_psp; then
enable_psp enable_psp
# shellcheck disable=SC2086 # shellcheck disable=SC2086
${minikube} start --force --memory="${MEMORY}" --cpus="${CPUS}" -b kubeadm --kubernetes-version="${KUBE_VERSION}" --driver="${VM_DRIVER}" --feature-gates="${K8S_FEATURE_GATES}" --cni="${CNI}" ${EXTRA_CONFIG} ${EXTRA_CONFIG_PSP} --wait-timeout="${MINIKUBE_WAIT_TIMEOUT}" --wait="${MINIKUBE_WAIT}" --delete-on-failure ${minikube} start --force --memory="${MEMORY}" --cpus="${CPUS}" -b kubeadm --kubernetes-version="${KUBE_VERSION}" --driver="${VM_DRIVER}" --feature-gates="${K8S_FEATURE_GATES}" --cni="${CNI}" ${EXTRA_CONFIG} ${EXTRA_CONFIG_PSP} --wait-timeout="${MINIKUBE_WAIT_TIMEOUT}" --wait="${MINIKUBE_WAIT}" --delete-on-failure "${DISK_CONFIG}"
else else
# This is a workaround to fix psp issues in minikube >1.6.2 and <1.11.0 # This is a workaround to fix psp issues in minikube >1.6.2 and <1.11.0
# shellcheck disable=SC2086 # shellcheck disable=SC2086
${minikube} start --force --memory="${MEMORY}" --cpus="${CPUS}" -b kubeadm --kubernetes-version="${KUBE_VERSION}" --driver="${VM_DRIVER}" --feature-gates="${K8S_FEATURE_GATES}" --cni="${CNI}" ${EXTRA_CONFIG} --wait-timeout="${MINIKUBE_WAIT_TIMEOUT}" --wait="${MINIKUBE_WAIT}" --delete-on-failure ${minikube} start --force --memory="${MEMORY}" --cpus="${CPUS}" -b kubeadm --kubernetes-version="${KUBE_VERSION}" --driver="${VM_DRIVER}" --feature-gates="${K8S_FEATURE_GATES}" --cni="${CNI}" ${EXTRA_CONFIG} --wait-timeout="${MINIKUBE_WAIT_TIMEOUT}" --wait="${MINIKUBE_WAIT}" --delete-on-failure "${DISK_CONFIG}"
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
${minikube} kubectl -- apply -f "$DIR"/psp.yaml ${minikube} kubectl -- apply -f "$DIR"/psp.yaml
${minikube} stop ${minikube} stop
# shellcheck disable=SC2086 # shellcheck disable=SC2086
${minikube} start --force --memory="${MEMORY}" --cpus="${CPUS}" -b kubeadm --kubernetes-version="${KUBE_VERSION}" --driver="${VM_DRIVER}" --feature-gates="${K8S_FEATURE_GATES}" --cni="${CNI}" ${EXTRA_CONFIG} ${EXTRA_CONFIG_PSP} --wait-timeout="${MINIKUBE_WAIT_TIMEOUT}" --wait="${MINIKUBE_WAIT}" ${minikube} start --force --memory="${MEMORY}" --cpus="${CPUS}" -b kubeadm --kubernetes-version="${KUBE_VERSION}" --driver="${VM_DRIVER}" --feature-gates="${K8S_FEATURE_GATES}" --cni="${CNI}" ${EXTRA_CONFIG} ${EXTRA_CONFIG_PSP} --wait-timeout="${MINIKUBE_WAIT_TIMEOUT}" --wait="${MINIKUBE_WAIT}" "${DISK_CONFIG}"
fi fi
# create a link so the default dataDirHostPath will work for this # create a link so the default dataDirHostPath will work for this

View File

@ -50,9 +50,19 @@ func prettify(v reflect.Value, indent int, buf *bytes.Buffer) {
for i, n := range names { for i, n := range names {
val := v.FieldByName(n) val := v.FieldByName(n)
ft, ok := v.Type().FieldByName(n)
if !ok {
panic(fmt.Sprintf("expected to find field %v on type %v, but was not found", n, v.Type()))
}
buf.WriteString(strings.Repeat(" ", indent+2)) buf.WriteString(strings.Repeat(" ", indent+2))
buf.WriteString(n + ": ") buf.WriteString(n + ": ")
prettify(val, indent+2, buf)
if tag := ft.Tag.Get("sensitive"); tag == "true" {
buf.WriteString("<sensitive>")
} else {
prettify(val, indent+2, buf)
}
if i < len(names)-1 { if i < len(names)-1 {
buf.WriteString(",\n") buf.WriteString(",\n")

View File

@ -8,6 +8,8 @@ import (
) )
// StringValue returns the string representation of a value. // StringValue returns the string representation of a value.
//
// Deprecated: Use Prettify instead.
func StringValue(i interface{}) string { func StringValue(i interface{}) string {
var buf bytes.Buffer var buf bytes.Buffer
stringValue(reflect.ValueOf(i), 0, &buf) stringValue(reflect.ValueOf(i), 0, &buf)

View File

@ -1,3 +1,4 @@
//go:build !go1.9
// +build !go1.9 // +build !go1.9
package aws package aws

View File

@ -1,3 +1,4 @@
//go:build go1.9
// +build go1.9 // +build go1.9
package aws package aws

View File

@ -1,3 +1,4 @@
//go:build !go1.7
// +build !go1.7 // +build !go1.7
package aws package aws

View File

@ -1,3 +1,4 @@
//go:build go1.7
// +build go1.7 // +build go1.7
package aws package aws

View File

@ -1,3 +1,4 @@
//go:build !go1.7
// +build !go1.7 // +build !go1.7
package credentials package credentials

View File

@ -1,3 +1,4 @@
//go:build go1.7
// +build go1.7 // +build go1.7
package credentials package credentials

View File

@ -1,3 +1,4 @@
//go:build !go1.9
// +build !go1.9 // +build !go1.9
package credentials package credentials

View File

@ -1,3 +1,4 @@
//go:build go1.9
// +build go1.9 // +build go1.9
package credentials package credentials

View File

@ -1,3 +1,4 @@
//go:build !windows
// +build !windows // +build !windows
package ssocreds package ssocreds

View File

@ -13,7 +13,6 @@ package ec2metadata
import ( import (
"bytes" "bytes"
"errors"
"io" "io"
"net/http" "net/http"
"net/url" "net/url"
@ -234,7 +233,8 @@ func unmarshalError(r *request.Request) {
// Response body format is not consistent between metadata endpoints. // Response body format is not consistent between metadata endpoints.
// Grab the error message as a string and include that as the source error // Grab the error message as a string and include that as the source error
r.Error = awserr.NewRequestFailure(awserr.New("EC2MetadataError", "failed to make EC2Metadata request", errors.New(b.String())), r.Error = awserr.NewRequestFailure(
awserr.New("EC2MetadataError", "failed to make EC2Metadata request\n"+b.String(), nil),
r.HTTPResponse.StatusCode, r.RequestID) r.HTTPResponse.StatusCode, r.RequestID)
} }

View File

@ -81,7 +81,6 @@ func decodeV3Endpoints(modelDef modelDefinition, opts DecodeModelOptions) (Resol
// Customization // Customization
for i := 0; i < len(ps); i++ { for i := 0; i < len(ps); i++ {
p := &ps[i] p := &ps[i]
custAddEC2Metadata(p)
custAddS3DualStack(p) custAddS3DualStack(p)
custRegionalS3(p) custRegionalS3(p)
custRmIotDataService(p) custRmIotDataService(p)
@ -140,19 +139,6 @@ func custAddDualstack(p *partition, svcName string) {
p.Services[svcName] = s p.Services[svcName] = s
} }
func custAddEC2Metadata(p *partition) {
p.Services["ec2metadata"] = service{
IsRegionalized: boxedFalse,
PartitionEndpoint: "aws-global",
Endpoints: endpoints{
"aws-global": endpoint{
Hostname: "169.254.169.254/latest",
Protocols: []string{"http"},
},
},
}
}
func custRmIotDataService(p *partition) { func custRmIotDataService(p *partition) {
delete(p.Services, "data.iot") delete(p.Services, "data.iot")
} }

View File

@ -32,7 +32,6 @@ const (
EuWest1RegionID = "eu-west-1" // Europe (Ireland). EuWest1RegionID = "eu-west-1" // Europe (Ireland).
EuWest2RegionID = "eu-west-2" // Europe (London). EuWest2RegionID = "eu-west-2" // Europe (London).
EuWest3RegionID = "eu-west-3" // Europe (Paris). EuWest3RegionID = "eu-west-3" // Europe (Paris).
InAmazon1RegionID = "in-amazon-1" // India (Begumpet).
MeSouth1RegionID = "me-south-1" // Middle East (Bahrain). MeSouth1RegionID = "me-south-1" // Middle East (Bahrain).
SaEast1RegionID = "sa-east-1" // South America (Sao Paulo). SaEast1RegionID = "sa-east-1" // South America (Sao Paulo).
UsEast1RegionID = "us-east-1" // US East (N. Virginia). UsEast1RegionID = "us-east-1" // US East (N. Virginia).
@ -101,7 +100,7 @@ var awsPartition = partition{
DNSSuffix: "amazonaws.com", DNSSuffix: "amazonaws.com",
RegionRegex: regionRegex{ RegionRegex: regionRegex{
Regexp: func() *regexp.Regexp { Regexp: func() *regexp.Regexp {
reg, _ := regexp.Compile("^(us|eu|ap|sa|ca|me|af|in)\\-\\w+\\-\\d+$") reg, _ := regexp.Compile("^(us|eu|ap|sa|ca|me|af)\\-\\w+\\-\\d+$")
return reg return reg
}(), }(),
}, },
@ -156,9 +155,6 @@ var awsPartition = partition{
"eu-west-3": region{ "eu-west-3": region{
Description: "Europe (Paris)", Description: "Europe (Paris)",
}, },
"in-amazon-1": region{
Description: "India (Begumpet)",
},
"me-south-1": region{ "me-south-1": region{
Description: "Middle East (Bahrain)", Description: "Middle East (Bahrain)",
}, },
@ -369,6 +365,30 @@ var awsPartition = partition{
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
"amplify": service{
Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-south-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"me-south-1": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{},
},
},
"amplifybackend": service{ "amplifybackend": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -652,9 +672,33 @@ var awsPartition = partition{
"eu-north-1": endpoint{}, "eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"us-east-1": endpoint{}, "fips-ca-central-1": endpoint{
"us-east-2": endpoint{}, Hostname: "api.fleethub.iot-fips.ca-central-1.amazonaws.com",
"us-west-2": endpoint{}, CredentialScope: credentialScope{
Region: "ca-central-1",
},
},
"fips-us-east-1": endpoint{
Hostname: "api.fleethub.iot-fips.us-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-1",
},
},
"fips-us-east-2": endpoint{
Hostname: "api.fleethub.iot-fips.us-east-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-2",
},
},
"fips-us-west-2": endpoint{
Hostname: "api.fleethub.iot-fips.us-west-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-2",
},
},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-2": endpoint{},
}, },
}, },
"api.mediatailor": service{ "api.mediatailor": service{
@ -771,6 +815,7 @@ var awsPartition = partition{
"appflow": service{ "appflow": service{
Endpoints: endpoints{ Endpoints: endpoints{
"af-south-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
@ -866,6 +911,7 @@ var awsPartition = partition{
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"fips": endpoint{ "fips": endpoint{
Hostname: "appstream2-fips.us-west-2.amazonaws.com", Hostname: "appstream2-fips.us-west-2.amazonaws.com",
CredentialScope: credentialScope{ CredentialScope: credentialScope{
@ -882,6 +928,7 @@ var awsPartition = partition{
"ap-east-1": endpoint{}, "ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-northeast-3": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
@ -900,6 +947,18 @@ var awsPartition = partition{
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
"aps": service{
Defaults: endpoint{
Protocols: []string{"https"},
},
Endpoints: endpoints{
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-2": endpoint{},
},
},
"athena": service{ "athena": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -907,6 +966,7 @@ var awsPartition = partition{
"ap-east-1": endpoint{}, "ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-northeast-3": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
@ -986,6 +1046,7 @@ var awsPartition = partition{
"ap-east-1": endpoint{}, "ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-northeast-3": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
@ -1357,6 +1418,7 @@ var awsPartition = partition{
"ap-east-1": endpoint{}, "ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-northeast-3": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
@ -1837,6 +1899,59 @@ var awsPartition = partition{
"us-east-1": endpoint{}, "us-east-1": endpoint{},
}, },
}, },
"data.jobs.iot": service{
Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"fips-ca-central-1": endpoint{
Hostname: "data.jobs.iot-fips.ca-central-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "ca-central-1",
},
},
"fips-us-east-1": endpoint{
Hostname: "data.jobs.iot-fips.us-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-1",
},
},
"fips-us-east-2": endpoint{
Hostname: "data.jobs.iot-fips.us-east-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-2",
},
},
"fips-us-west-1": endpoint{
Hostname: "data.jobs.iot-fips.us-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-1",
},
},
"fips-us-west-2": endpoint{
Hostname: "data.jobs.iot-fips.us-west-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-2",
},
},
"me-south-1": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{},
},
},
"data.mediastore": service{ "data.mediastore": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -1884,6 +1999,7 @@ var awsPartition = partition{
"ap-east-1": endpoint{}, "ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-northeast-3": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
@ -2146,6 +2262,7 @@ var awsPartition = partition{
"ap-east-1": endpoint{}, "ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-northeast-3": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
@ -2373,17 +2490,6 @@ var awsPartition = partition{
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
"ec2metadata": service{
PartitionEndpoint: "aws-global",
IsRegionalized: boxedFalse,
Endpoints: endpoints{
"aws-global": endpoint{
Hostname: "169.254.169.254/latest",
Protocols: []string{"http"},
},
},
},
"ecs": service{ "ecs": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -2873,11 +2979,41 @@ var awsPartition = partition{
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"sa-east-1": endpoint{}, "fips-ca-central-1": endpoint{
"us-east-1": endpoint{}, Hostname: "emr-containers-fips.ca-central-1.amazonaws.com",
"us-east-2": endpoint{}, CredentialScope: credentialScope{
"us-west-1": endpoint{}, Region: "ca-central-1",
"us-west-2": endpoint{}, },
},
"fips-us-east-1": endpoint{
Hostname: "emr-containers-fips.us-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-1",
},
},
"fips-us-east-2": endpoint{
Hostname: "emr-containers-fips.us-east-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-2",
},
},
"fips-us-west-1": endpoint{
Hostname: "emr-containers-fips.us-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-1",
},
},
"fips-us-west-2": endpoint{
Hostname: "emr-containers-fips.us-west-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-2",
},
},
"sa-east-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{},
}, },
}, },
"entitlement.marketplace": service{ "entitlement.marketplace": service{
@ -3051,6 +3187,7 @@ var awsPartition = partition{
"ap-east-1": endpoint{}, "ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-northeast-3": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
@ -3249,6 +3386,17 @@ var awsPartition = partition{
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
"frauddetector": service{
Endpoints: endpoints{
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-2": endpoint{},
},
},
"fsx": service{ "fsx": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -3256,6 +3404,7 @@ var awsPartition = partition{
"ap-east-1": endpoint{}, "ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-northeast-3": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
@ -3559,6 +3708,8 @@ var awsPartition = partition{
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-2": endpoint{},
}, },
}, },
"honeycode": service{ "honeycode": service{
@ -3586,6 +3737,18 @@ var awsPartition = partition{
}, },
}, },
}, },
"identity-chime": service{
Endpoints: endpoints{
"us-east-1": endpoint{},
"us-east-1-fips": endpoint{
Hostname: "identity-chime-fips.us-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-1",
},
},
},
},
"identitystore": service{ "identitystore": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -3679,18 +3842,49 @@ var awsPartition = partition{
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"me-south-1": endpoint{}, "fips-ca-central-1": endpoint{
"sa-east-1": endpoint{}, Hostname: "iot-fips.ca-central-1.amazonaws.com",
"us-east-1": endpoint{}, CredentialScope: credentialScope{
"us-east-2": endpoint{}, Service: "execute-api",
"us-west-1": endpoint{}, },
"us-west-2": endpoint{}, },
"fips-us-east-1": endpoint{
Hostname: "iot-fips.us-east-1.amazonaws.com",
CredentialScope: credentialScope{
Service: "execute-api",
},
},
"fips-us-east-2": endpoint{
Hostname: "iot-fips.us-east-2.amazonaws.com",
CredentialScope: credentialScope{
Service: "execute-api",
},
},
"fips-us-west-1": endpoint{
Hostname: "iot-fips.us-west-1.amazonaws.com",
CredentialScope: credentialScope{
Service: "execute-api",
},
},
"fips-us-west-2": endpoint{
Hostname: "iot-fips.us-west-2.amazonaws.com",
CredentialScope: credentialScope{
Service: "execute-api",
},
},
"me-south-1": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{},
}, },
}, },
"iotanalytics": service{ "iotanalytics": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
@ -3794,12 +3988,42 @@ var awsPartition = partition{
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"me-south-1": endpoint{}, "fips-ca-central-1": endpoint{
"sa-east-1": endpoint{}, Hostname: "api.tunneling.iot-fips.ca-central-1.amazonaws.com",
"us-east-1": endpoint{}, CredentialScope: credentialScope{
"us-east-2": endpoint{}, Region: "ca-central-1",
"us-west-1": endpoint{}, },
"us-west-2": endpoint{}, },
"fips-us-east-1": endpoint{
Hostname: "api.tunneling.iot-fips.us-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-1",
},
},
"fips-us-east-2": endpoint{
Hostname: "api.tunneling.iot-fips.us-east-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-2",
},
},
"fips-us-west-1": endpoint{
Hostname: "api.tunneling.iot-fips.us-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-1",
},
},
"fips-us-west-2": endpoint{
Hostname: "api.tunneling.iot-fips.us-west-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-2",
},
},
"me-south-1": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{},
}, },
}, },
"iotthingsgraph": service{ "iotthingsgraph": service{
@ -3820,6 +4044,18 @@ var awsPartition = partition{
"iotwireless": service{ "iotwireless": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{
Hostname: "api.iotwireless.ap-northeast-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "ap-northeast-1",
},
},
"ap-southeast-2": endpoint{
Hostname: "api.iotwireless.ap-southeast-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "ap-southeast-2",
},
},
"eu-west-1": endpoint{ "eu-west-1": endpoint{
Hostname: "api.iotwireless.eu-west-1.amazonaws.com", Hostname: "api.iotwireless.eu-west-1.amazonaws.com",
CredentialScope: credentialScope{ CredentialScope: credentialScope{
@ -3832,6 +4068,12 @@ var awsPartition = partition{
Region: "us-east-1", Region: "us-east-1",
}, },
}, },
"us-west-2": endpoint{
Hostname: "api.iotwireless.us-west-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-2",
},
},
}, },
}, },
"kafka": service{ "kafka": service{
@ -4433,6 +4675,7 @@ var awsPartition = partition{
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"sa-east-1": endpoint{}, "sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-1": endpoint{}, "us-west-1": endpoint{},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
@ -4451,6 +4694,18 @@ var awsPartition = partition{
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
"messaging-chime": service{
Endpoints: endpoints{
"us-east-1": endpoint{},
"us-east-1-fips": endpoint{
Hostname: "messaging-chime-fips.us-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-1",
},
},
},
},
"metering.marketplace": service{ "metering.marketplace": service{
Defaults: endpoint{ Defaults: endpoint{
CredentialScope: credentialScope{ CredentialScope: credentialScope{
@ -4815,6 +5070,12 @@ var awsPartition = partition{
Region: "eu-west-2", Region: "eu-west-2",
}, },
}, },
"eu-west-3": endpoint{
Hostname: "oidc.eu-west-3.amazonaws.com",
CredentialScope: credentialScope{
Region: "eu-west-3",
},
},
"us-east-1": endpoint{ "us-east-1": endpoint{
Hostname: "oidc.us-east-1.amazonaws.com", Hostname: "oidc.us-east-1.amazonaws.com",
CredentialScope: credentialScope{ CredentialScope: credentialScope{
@ -4895,6 +5156,7 @@ var awsPartition = partition{
"ap-east-1": endpoint{}, "ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-northeast-3": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
@ -5141,6 +5403,7 @@ var awsPartition = partition{
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"fips-us-east-1": endpoint{ "fips-us-east-1": endpoint{
Hostname: "qldb-fips.us-east-1.amazonaws.com", Hostname: "qldb-fips.us-east-1.amazonaws.com",
CredentialScope: credentialScope{ CredentialScope: credentialScope{
@ -5463,6 +5726,17 @@ var awsPartition = partition{
}, },
}, },
}, },
"route53-recovery-control-config": service{
Endpoints: endpoints{
"aws-global": endpoint{
Hostname: "route53-recovery-control-config.us-west-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-2",
},
},
},
},
"route53domains": service{ "route53domains": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -6303,6 +6577,7 @@ var awsPartition = partition{
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"fips-us-east-1": endpoint{ "fips-us-east-1": endpoint{
Hostname: "session.qldb-fips.us-east-1.amazonaws.com", Hostname: "session.qldb-fips.us-east-1.amazonaws.com",
CredentialScope: credentialScope{ CredentialScope: credentialScope{
@ -6738,6 +7013,7 @@ var awsPartition = partition{
"ap-east-1": endpoint{}, "ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-northeast-3": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
@ -6851,15 +7127,9 @@ var awsPartition = partition{
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"in-amazon-1": endpoint{ "me-south-1": endpoint{},
Hostname: "sts.ap-south-1.amazonaws.com", "sa-east-1": endpoint{},
CredentialScope: credentialScope{ "us-east-1": endpoint{},
Region: "ap-south-1",
},
},
"me-south-1": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{},
"us-east-1-fips": endpoint{ "us-east-1-fips": endpoint{
Hostname: "sts-fips.us-east-1.amazonaws.com", Hostname: "sts-fips.us-east-1.amazonaws.com",
CredentialScope: credentialScope{ CredentialScope: credentialScope{
@ -7751,9 +8021,17 @@ var awscnPartition = partition{
"cn-northwest-1": endpoint{}, "cn-northwest-1": endpoint{},
}, },
}, },
"data.jobs.iot": service{
Endpoints: endpoints{
"cn-north-1": endpoint{},
"cn-northwest-1": endpoint{},
},
},
"dax": service{ "dax": service{
Endpoints: endpoints{ Endpoints: endpoints{
"cn-north-1": endpoint{},
"cn-northwest-1": endpoint{}, "cn-northwest-1": endpoint{},
}, },
}, },
@ -7814,17 +8092,6 @@ var awscnPartition = partition{
"cn-northwest-1": endpoint{}, "cn-northwest-1": endpoint{},
}, },
}, },
"ec2metadata": service{
PartitionEndpoint: "aws-global",
IsRegionalized: boxedFalse,
Endpoints: endpoints{
"aws-global": endpoint{
Hostname: "169.254.169.254/latest",
Protocols: []string{"http"},
},
},
},
"ecs": service{ "ecs": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -7892,6 +8159,13 @@ var awscnPartition = partition{
"cn-northwest-1": endpoint{}, "cn-northwest-1": endpoint{},
}, },
}, },
"emr-containers": service{
Endpoints: endpoints{
"cn-north-1": endpoint{},
"cn-northwest-1": endpoint{},
},
},
"es": service{ "es": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -7913,6 +8187,15 @@ var awscnPartition = partition{
"cn-northwest-1": endpoint{}, "cn-northwest-1": endpoint{},
}, },
}, },
"fms": service{
Defaults: endpoint{
Protocols: []string{"https"},
},
Endpoints: endpoints{
"cn-north-1": endpoint{},
"cn-northwest-1": endpoint{},
},
},
"fsx": service{ "fsx": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -7923,7 +8206,8 @@ var awscnPartition = partition{
"gamelift": service{ "gamelift": service{
Endpoints: endpoints{ Endpoints: endpoints{
"cn-north-1": endpoint{}, "cn-north-1": endpoint{},
"cn-northwest-1": endpoint{},
}, },
}, },
"glacier": service{ "glacier": service{
@ -8108,6 +8392,12 @@ var awscnPartition = partition{
"neptune": service{ "neptune": service{
Endpoints: endpoints{ Endpoints: endpoints{
"cn-north-1": endpoint{
Hostname: "rds.cn-north-1.amazonaws.com.cn",
CredentialScope: credentialScope{
Region: "cn-north-1",
},
},
"cn-northwest-1": endpoint{ "cn-northwest-1": endpoint{
Hostname: "rds.cn-northwest-1.amazonaws.com.cn", Hostname: "rds.cn-northwest-1.amazonaws.com.cn",
CredentialScope: credentialScope{ CredentialScope: credentialScope{
@ -8415,6 +8705,13 @@ var awscnPartition = partition{
}, },
}, },
}, },
"transcribestreaming": service{
Endpoints: endpoints{
"cn-north-1": endpoint{},
"cn-northwest-1": endpoint{},
},
},
"transfer": service{ "transfer": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -8936,6 +9233,25 @@ var awsusgovPartition = partition{
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
}, },
"data.jobs.iot": service{
Endpoints: endpoints{
"fips-us-gov-east-1": endpoint{
Hostname: "data.jobs.iot-fips.us-gov-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-gov-east-1",
},
},
"fips-us-gov-west-1": endpoint{
Hostname: "data.jobs.iot-fips.us-gov-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-gov-west-1",
},
},
"us-gov-east-1": endpoint{},
"us-gov-west-1": endpoint{},
},
},
"datasync": service{ "datasync": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -9058,17 +9374,6 @@ var awsusgovPartition = partition{
}, },
}, },
}, },
"ec2metadata": service{
PartitionEndpoint: "aws-global",
IsRegionalized: boxedFalse,
Endpoints: endpoints{
"aws-global": endpoint{
Hostname: "169.254.169.254/latest",
Protocols: []string{"http"},
},
},
},
"ecs": service{ "ecs": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -9454,6 +9759,18 @@ var awsusgovPartition = partition{
}, },
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"fips-us-gov-east-1": endpoint{
Hostname: "iot-fips.us-gov-east-1.amazonaws.com",
CredentialScope: credentialScope{
Service: "execute-api",
},
},
"fips-us-gov-west-1": endpoint{
Hostname: "iot-fips.us-gov-west-1.amazonaws.com",
CredentialScope: credentialScope{
Service: "execute-api",
},
},
"us-gov-east-1": endpoint{}, "us-gov-east-1": endpoint{},
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
@ -9461,6 +9778,18 @@ var awsusgovPartition = partition{
"iotsecuredtunneling": service{ "iotsecuredtunneling": service{
Endpoints: endpoints{ Endpoints: endpoints{
"fips-us-gov-east-1": endpoint{
Hostname: "api.tunneling.iot-fips.us-gov-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-gov-east-1",
},
},
"fips-us-gov-west-1": endpoint{
Hostname: "api.tunneling.iot-fips.us-gov-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-gov-west-1",
},
},
"us-gov-east-1": endpoint{}, "us-gov-east-1": endpoint{},
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
@ -9633,6 +9962,25 @@ var awsusgovPartition = partition{
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
}, },
"mq": service{
Endpoints: endpoints{
"fips-us-gov-east-1": endpoint{
Hostname: "mq-fips.us-gov-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-gov-east-1",
},
},
"fips-us-gov-west-1": endpoint{
Hostname: "mq-fips.us-gov-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-gov-west-1",
},
},
"us-gov-east-1": endpoint{},
"us-gov-west-1": endpoint{},
},
},
"neptune": service{ "neptune": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -10522,17 +10870,6 @@ var awsisoPartition = partition{
"us-iso-east-1": endpoint{}, "us-iso-east-1": endpoint{},
}, },
}, },
"ec2metadata": service{
PartitionEndpoint: "aws-global",
IsRegionalized: boxedFalse,
Endpoints: endpoints{
"aws-global": endpoint{
Hostname: "169.254.169.254/latest",
Protocols: []string{"http"},
},
},
},
"ecs": service{ "ecs": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -10642,6 +10979,12 @@ var awsisoPartition = partition{
"us-iso-east-1": endpoint{}, "us-iso-east-1": endpoint{},
}, },
}, },
"license-manager": service{
Endpoints: endpoints{
"us-iso-east-1": endpoint{},
},
},
"logs": service{ "logs": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -10703,6 +11046,12 @@ var awsisoPartition = partition{
}, },
}, },
}, },
"route53resolver": service{
Endpoints: endpoints{
"us-iso-east-1": endpoint{},
},
},
"runtime.sagemaker": service{ "runtime.sagemaker": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -10923,6 +11272,12 @@ var awsisobPartition = partition{
"us-isob-east-1": endpoint{}, "us-isob-east-1": endpoint{},
}, },
}, },
"ds": service{
Endpoints: endpoints{
"us-isob-east-1": endpoint{},
},
},
"dynamodb": service{ "dynamodb": service{
Defaults: endpoint{ Defaults: endpoint{
Protocols: []string{"http", "https"}, Protocols: []string{"http", "https"},
@ -10939,17 +11294,6 @@ var awsisobPartition = partition{
"us-isob-east-1": endpoint{}, "us-isob-east-1": endpoint{},
}, },
}, },
"ec2metadata": service{
PartitionEndpoint: "aws-global",
IsRegionalized: boxedFalse,
Endpoints: endpoints{
"aws-global": endpoint{
Hostname: "169.254.169.254/latest",
Protocols: []string{"http"},
},
},
},
"ecs": service{ "ecs": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -11155,6 +11499,12 @@ var awsisobPartition = partition{
}, },
"swf": service{ "swf": service{
Endpoints: endpoints{
"us-isob-east-1": endpoint{},
},
},
"tagging": service{
Endpoints: endpoints{ Endpoints: endpoints{
"us-isob-east-1": endpoint{}, "us-isob-east-1": endpoint{},
}, },

View File

@ -48,6 +48,9 @@ type Options struct {
// This option is ignored if StrictMatching is enabled. // This option is ignored if StrictMatching is enabled.
ResolveUnknownService bool ResolveUnknownService bool
// Specifies the EC2 Instance Metadata Service default endpoint selection mode (IPv4 or IPv6)
EC2MetadataEndpointMode EC2IMDSEndpointModeState
// STS Regional Endpoint flag helps with resolving the STS endpoint // STS Regional Endpoint flag helps with resolving the STS endpoint
STSRegionalEndpoint STSRegionalEndpoint STSRegionalEndpoint STSRegionalEndpoint
@ -55,6 +58,33 @@ type Options struct {
S3UsEast1RegionalEndpoint S3UsEast1RegionalEndpoint S3UsEast1RegionalEndpoint S3UsEast1RegionalEndpoint
} }
// EC2IMDSEndpointModeState is an enum configuration variable describing the client endpoint mode.
type EC2IMDSEndpointModeState uint
// Enumeration values for EC2IMDSEndpointModeState
const (
EC2IMDSEndpointModeStateUnset EC2IMDSEndpointModeState = iota
EC2IMDSEndpointModeStateIPv4
EC2IMDSEndpointModeStateIPv6
)
// SetFromString sets the EC2IMDSEndpointModeState based on the provided string value. Unknown values will default to EC2IMDSEndpointModeStateUnset
func (e *EC2IMDSEndpointModeState) SetFromString(v string) error {
v = strings.TrimSpace(v)
switch {
case len(v) == 0:
*e = EC2IMDSEndpointModeStateUnset
case strings.EqualFold(v, "IPv6"):
*e = EC2IMDSEndpointModeStateIPv6
case strings.EqualFold(v, "IPv4"):
*e = EC2IMDSEndpointModeStateIPv4
default:
return fmt.Errorf("unknown EC2 IMDS endpoint mode, must be either IPv6 or IPv4")
}
return nil
}
// STSRegionalEndpoint is an enum for the states of the STS Regional Endpoint // STSRegionalEndpoint is an enum for the states of the STS Regional Endpoint
// options. // options.
type STSRegionalEndpoint int type STSRegionalEndpoint int
@ -247,7 +277,7 @@ func RegionsForService(ps []Partition, partitionID, serviceID string) (map[strin
if p.ID() != partitionID { if p.ID() != partitionID {
continue continue
} }
if _, ok := p.p.Services[serviceID]; !ok { if _, ok := p.p.Services[serviceID]; !(ok || serviceID == Ec2metadataServiceID) {
break break
} }
@ -333,6 +363,7 @@ func (p Partition) Regions() map[string]Region {
// enumerating over the services in a partition. // enumerating over the services in a partition.
func (p Partition) Services() map[string]Service { func (p Partition) Services() map[string]Service {
ss := make(map[string]Service, len(p.p.Services)) ss := make(map[string]Service, len(p.p.Services))
for id := range p.p.Services { for id := range p.p.Services {
ss[id] = Service{ ss[id] = Service{
id: id, id: id,
@ -340,6 +371,15 @@ func (p Partition) Services() map[string]Service {
} }
} }
// Since we have removed the customization that injected this into the model
// we still need to pretend that this is a modeled service.
if _, ok := ss[Ec2metadataServiceID]; !ok {
ss[Ec2metadataServiceID] = Service{
id: Ec2metadataServiceID,
p: p.p,
}
}
return ss return ss
} }
@ -400,7 +440,18 @@ func (s Service) ResolveEndpoint(region string, opts ...func(*Options)) (Resolve
// an URL that can be resolved to a instance of a service. // an URL that can be resolved to a instance of a service.
func (s Service) Regions() map[string]Region { func (s Service) Regions() map[string]Region {
rs := map[string]Region{} rs := map[string]Region{}
for id := range s.p.Services[s.id].Endpoints {
service, ok := s.p.Services[s.id]
// Since ec2metadata customization has been removed we need to check
// if it was defined in non-standard endpoints.json file. If it's not
// then we can return the empty map as there is no regional-endpoints for IMDS.
// Otherwise, we iterate need to iterate the non-standard model.
if s.id == Ec2metadataServiceID && !ok {
return rs
}
for id := range service.Endpoints {
if r, ok := s.p.Regions[id]; ok { if r, ok := s.p.Regions[id]; ok {
rs[id] = Region{ rs[id] = Region{
id: id, id: id,

View File

@ -7,6 +7,11 @@ import (
"strings" "strings"
) )
const (
ec2MetadataEndpointIPv6 = "http://[fd00:ec2::254]/latest"
ec2MetadataEndpointIPv4 = "http://169.254.169.254/latest"
)
var regionValidationRegex = regexp.MustCompile(`^[[:alnum:]]([[:alnum:]\-]*[[:alnum:]])?$`) var regionValidationRegex = regexp.MustCompile(`^[[:alnum:]]([[:alnum:]\-]*[[:alnum:]])?$`)
type partitions []partition type partitions []partition
@ -102,6 +107,12 @@ func (p partition) EndpointFor(service, region string, opts ...func(*Options)) (
opt.Set(opts...) opt.Set(opts...)
s, hasService := p.Services[service] s, hasService := p.Services[service]
if service == Ec2metadataServiceID && !hasService {
endpoint := getEC2MetadataEndpoint(p.ID, service, opt.EC2MetadataEndpointMode)
return endpoint, nil
}
if len(service) == 0 || !(hasService || opt.ResolveUnknownService) { if len(service) == 0 || !(hasService || opt.ResolveUnknownService) {
// Only return error if the resolver will not fallback to creating // Only return error if the resolver will not fallback to creating
// endpoint based on service endpoint ID passed in. // endpoint based on service endpoint ID passed in.
@ -129,6 +140,31 @@ func (p partition) EndpointFor(service, region string, opts ...func(*Options)) (
return e.resolve(service, p.ID, region, p.DNSSuffix, defs, opt) return e.resolve(service, p.ID, region, p.DNSSuffix, defs, opt)
} }
func getEC2MetadataEndpoint(partitionID, service string, mode EC2IMDSEndpointModeState) ResolvedEndpoint {
switch mode {
case EC2IMDSEndpointModeStateIPv6:
return ResolvedEndpoint{
URL: ec2MetadataEndpointIPv6,
PartitionID: partitionID,
SigningRegion: "aws-global",
SigningName: service,
SigningNameDerived: true,
SigningMethod: "v4",
}
case EC2IMDSEndpointModeStateIPv4:
fallthrough
default:
return ResolvedEndpoint{
URL: ec2MetadataEndpointIPv4,
PartitionID: partitionID,
SigningRegion: "aws-global",
SigningName: service,
SigningNameDerived: true,
SigningMethod: "v4",
}
}
}
func serviceList(ss services) []string { func serviceList(ss services) []string {
list := make([]string, 0, len(ss)) list := make([]string, 0, len(ss))
for k := range ss { for k := range ss {

View File

@ -1,3 +1,4 @@
//go:build codegen
// +build codegen // +build codegen
package endpoints package endpoints

View File

@ -1,3 +1,4 @@
//go:build !go1.8
// +build !go1.8 // +build !go1.8
package request package request

View File

@ -1,3 +1,4 @@
//go:build go1.8
// +build go1.8 // +build go1.8
package request package request

View File

@ -1,3 +1,4 @@
//go:build go1.7
// +build go1.7 // +build go1.7
package request package request

View File

@ -1,3 +1,4 @@
//go:build !go1.7
// +build !go1.7 // +build !go1.7
package request package request

View File

@ -1,3 +1,4 @@
//go:build go1.13
// +build go1.13 // +build go1.13
package session package session

View File

@ -1,3 +1,4 @@
//go:build !go1.13 && go1.7
// +build !go1.13,go1.7 // +build !go1.13,go1.7
package session package session

View File

@ -1,3 +1,4 @@
//go:build !go1.6 && go1.5
// +build !go1.6,go1.5 // +build !go1.6,go1.5
package session package session

View File

@ -1,3 +1,4 @@
//go:build !go1.7 && go1.6
// +build !go1.7,go1.6 // +build !go1.7,go1.6
package session package session

View File

@ -283,7 +283,7 @@ component must be enclosed in square brackets.
The custom EC2 IMDS endpoint can also be specified via the Session options. The custom EC2 IMDS endpoint can also be specified via the Session options.
sess, err := session.NewSessionWithOptions(session.Options{ sess, err := session.NewSessionWithOptions(session.Options{
EC2IMDSEndpoint: "http://[::1]", EC2MetadataEndpoint: "http://[::1]",
}) })
*/ */
package session package session

View File

@ -161,10 +161,15 @@ type envConfig struct {
// AWS_S3_USE_ARN_REGION=true // AWS_S3_USE_ARN_REGION=true
S3UseARNRegion bool S3UseARNRegion bool
// Specifies the alternative endpoint to use for EC2 IMDS. // Specifies the EC2 Instance Metadata Service endpoint to use. If specified it overrides EC2IMDSEndpointMode.
// //
// AWS_EC2_METADATA_SERVICE_ENDPOINT=http://[::1] // AWS_EC2_METADATA_SERVICE_ENDPOINT=http://[::1]
EC2IMDSEndpoint string EC2IMDSEndpoint string
// Specifies the EC2 Instance Metadata Service default endpoint selection mode (IPv4 or IPv6)
//
// AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE=IPv6
EC2IMDSEndpointMode endpoints.EC2IMDSEndpointModeState
} }
var ( var (
@ -231,6 +236,9 @@ var (
ec2IMDSEndpointEnvKey = []string{ ec2IMDSEndpointEnvKey = []string{
"AWS_EC2_METADATA_SERVICE_ENDPOINT", "AWS_EC2_METADATA_SERVICE_ENDPOINT",
} }
ec2IMDSEndpointModeEnvKey = []string{
"AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE",
}
useCABundleKey = []string{ useCABundleKey = []string{
"AWS_CA_BUNDLE", "AWS_CA_BUNDLE",
} }
@ -364,6 +372,9 @@ func envConfigLoad(enableSharedConfig bool) (envConfig, error) {
} }
setFromEnvVal(&cfg.EC2IMDSEndpoint, ec2IMDSEndpointEnvKey) setFromEnvVal(&cfg.EC2IMDSEndpoint, ec2IMDSEndpointEnvKey)
if err := setEC2IMDSEndpointMode(&cfg.EC2IMDSEndpointMode, ec2IMDSEndpointModeEnvKey); err != nil {
return envConfig{}, err
}
return cfg, nil return cfg, nil
} }
@ -376,3 +387,17 @@ func setFromEnvVal(dst *string, keys []string) {
} }
} }
} }
func setEC2IMDSEndpointMode(mode *endpoints.EC2IMDSEndpointModeState, keys []string) error {
for _, k := range keys {
value := os.Getenv(k)
if len(value) == 0 {
continue
}
if err := mode.SetFromString(value); err != nil {
return fmt.Errorf("invalid value for environment variable, %s=%s, %v", k, value, err)
}
return nil
}
return nil
}

View File

@ -283,8 +283,8 @@ type Options struct {
Handlers request.Handlers Handlers request.Handlers
// Allows specifying a custom endpoint to be used by the EC2 IMDS client // Allows specifying a custom endpoint to be used by the EC2 IMDS client
// when making requests to the EC2 IMDS API. The must endpoint value must // when making requests to the EC2 IMDS API. The endpoint value should
// include protocol prefix. // include the URI scheme. If the scheme is not present it will be defaulted to http.
// //
// If unset, will the EC2 IMDS client will use its default endpoint. // If unset, will the EC2 IMDS client will use its default endpoint.
// //
@ -298,6 +298,11 @@ type Options struct {
// //
// AWS_EC2_METADATA_SERVICE_ENDPOINT=http://[::1] // AWS_EC2_METADATA_SERVICE_ENDPOINT=http://[::1]
EC2IMDSEndpoint string EC2IMDSEndpoint string
// Specifies the EC2 Instance Metadata Service default endpoint selection mode (IPv4 or IPv6)
//
// AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE=IPv6
EC2IMDSEndpointMode endpoints.EC2IMDSEndpointModeState
} }
// NewSessionWithOptions returns a new Session created from SDK defaults, config files, // NewSessionWithOptions returns a new Session created from SDK defaults, config files,
@ -375,19 +380,23 @@ func Must(sess *Session, err error) *Session {
// Wraps the endpoint resolver with a resolver that will return a custom // Wraps the endpoint resolver with a resolver that will return a custom
// endpoint for EC2 IMDS. // endpoint for EC2 IMDS.
func wrapEC2IMDSEndpoint(resolver endpoints.Resolver, endpoint string) endpoints.Resolver { func wrapEC2IMDSEndpoint(resolver endpoints.Resolver, endpoint string, mode endpoints.EC2IMDSEndpointModeState) endpoints.Resolver {
return endpoints.ResolverFunc( return endpoints.ResolverFunc(
func(service, region string, opts ...func(*endpoints.Options)) ( func(service, region string, opts ...func(*endpoints.Options)) (
endpoints.ResolvedEndpoint, error, endpoints.ResolvedEndpoint, error,
) { ) {
if service == ec2MetadataServiceID { if service == ec2MetadataServiceID && len(endpoint) > 0 {
return endpoints.ResolvedEndpoint{ return endpoints.ResolvedEndpoint{
URL: endpoint, URL: endpoint,
SigningName: ec2MetadataServiceID, SigningName: ec2MetadataServiceID,
SigningRegion: region, SigningRegion: region,
}, nil }, nil
} else if service == ec2MetadataServiceID {
opts = append(opts, func(o *endpoints.Options) {
o.EC2MetadataEndpointMode = mode
})
} }
return resolver.EndpointFor(service, region) return resolver.EndpointFor(service, region, opts...)
}) })
} }
@ -404,8 +413,8 @@ func deprecatedNewSession(envCfg envConfig, cfgs ...*aws.Config) *Session {
cfg.EndpointResolver = endpoints.DefaultResolver() cfg.EndpointResolver = endpoints.DefaultResolver()
} }
if len(envCfg.EC2IMDSEndpoint) != 0 { if !(len(envCfg.EC2IMDSEndpoint) == 0 && envCfg.EC2IMDSEndpointMode == endpoints.EC2IMDSEndpointModeStateUnset) {
cfg.EndpointResolver = wrapEC2IMDSEndpoint(cfg.EndpointResolver, envCfg.EC2IMDSEndpoint) cfg.EndpointResolver = wrapEC2IMDSEndpoint(cfg.EndpointResolver, envCfg.EC2IMDSEndpoint, envCfg.EC2IMDSEndpointMode)
} }
cfg.Credentials = defaults.CredChain(cfg, handlers) cfg.Credentials = defaults.CredChain(cfg, handlers)
@ -737,12 +746,32 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config,
endpoints.LegacyS3UsEast1Endpoint, endpoints.LegacyS3UsEast1Endpoint,
}) })
ec2IMDSEndpoint := sessOpts.EC2IMDSEndpoint var ec2IMDSEndpoint string
if len(ec2IMDSEndpoint) == 0 { for _, v := range []string{
ec2IMDSEndpoint = envCfg.EC2IMDSEndpoint sessOpts.EC2IMDSEndpoint,
envCfg.EC2IMDSEndpoint,
sharedCfg.EC2IMDSEndpoint,
} {
if len(v) != 0 {
ec2IMDSEndpoint = v
break
}
} }
if len(ec2IMDSEndpoint) != 0 {
cfg.EndpointResolver = wrapEC2IMDSEndpoint(cfg.EndpointResolver, ec2IMDSEndpoint) var endpointMode endpoints.EC2IMDSEndpointModeState
for _, v := range []endpoints.EC2IMDSEndpointModeState{
sessOpts.EC2IMDSEndpointMode,
envCfg.EC2IMDSEndpointMode,
sharedCfg.EC2IMDSEndpointMode,
} {
if v != endpoints.EC2IMDSEndpointModeStateUnset {
endpointMode = v
break
}
}
if len(ec2IMDSEndpoint) != 0 || endpointMode != endpoints.EC2IMDSEndpointModeStateUnset {
cfg.EndpointResolver = wrapEC2IMDSEndpoint(cfg.EndpointResolver, ec2IMDSEndpoint, endpointMode)
} }
// Configure credentials if not already set by the user when creating the // Configure credentials if not already set by the user when creating the

View File

@ -66,6 +66,12 @@ const (
// S3 ARN Region Usage // S3 ARN Region Usage
s3UseARNRegionKey = "s3_use_arn_region" s3UseARNRegionKey = "s3_use_arn_region"
// EC2 IMDS Endpoint Mode
ec2MetadataServiceEndpointModeKey = "ec2_metadata_service_endpoint_mode"
// EC2 IMDS Endpoint
ec2MetadataServiceEndpointKey = "ec2_metadata_service_endpoint"
) )
// sharedConfig represents the configuration fields of the SDK config files. // sharedConfig represents the configuration fields of the SDK config files.
@ -145,6 +151,16 @@ type sharedConfig struct {
// //
// s3_use_arn_region=true // s3_use_arn_region=true
S3UseARNRegion bool S3UseARNRegion bool
// Specifies the EC2 Instance Metadata Service default endpoint selection mode (IPv4 or IPv6)
//
// ec2_metadata_service_endpoint_mode=IPv6
EC2IMDSEndpointMode endpoints.EC2IMDSEndpointModeState
// Specifies the EC2 Instance Metadata Service endpoint to use. If specified it overrides EC2IMDSEndpointMode.
//
// ec2_metadata_service_endpoint=http://fd00:ec2::254
EC2IMDSEndpoint string
} }
type sharedConfigFile struct { type sharedConfigFile struct {
@ -334,6 +350,12 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e
updateString(&cfg.SSORegion, section, ssoRegionKey) updateString(&cfg.SSORegion, section, ssoRegionKey)
updateString(&cfg.SSORoleName, section, ssoRoleNameKey) updateString(&cfg.SSORoleName, section, ssoRoleNameKey)
updateString(&cfg.SSOStartURL, section, ssoStartURL) updateString(&cfg.SSOStartURL, section, ssoStartURL)
if err := updateEC2MetadataServiceEndpointMode(&cfg.EC2IMDSEndpointMode, section, ec2MetadataServiceEndpointModeKey); err != nil {
return fmt.Errorf("failed to load %s from shared config, %s, %v",
ec2MetadataServiceEndpointModeKey, file.Filename, err)
}
updateString(&cfg.EC2IMDSEndpoint, section, ec2MetadataServiceEndpointKey)
} }
updateString(&cfg.CredentialProcess, section, credentialProcessKey) updateString(&cfg.CredentialProcess, section, credentialProcessKey)
@ -364,6 +386,14 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e
return nil return nil
} }
func updateEC2MetadataServiceEndpointMode(endpointMode *endpoints.EC2IMDSEndpointModeState, section ini.Section, key string) error {
if !section.Has(key) {
return nil
}
value := section.String(key)
return endpointMode.SetFromString(value)
}
func (cfg *sharedConfig) validateCredentialsConfig(profile string) error { func (cfg *sharedConfig) validateCredentialsConfig(profile string) error {
if err := cfg.validateCredentialsRequireARN(profile); err != nil { if err := cfg.validateCredentialsRequireARN(profile); err != nil {
return err return err

View File

@ -34,23 +34,23 @@ func (m mapRule) IsValid(value string) bool {
return ok return ok
} }
// whitelist is a generic rule for whitelisting // allowList is a generic rule for allow listing
type whitelist struct { type allowList struct {
rule rule
} }
// IsValid for whitelist checks if the value is within the whitelist // IsValid for allow list checks if the value is within the allow list
func (w whitelist) IsValid(value string) bool { func (w allowList) IsValid(value string) bool {
return w.rule.IsValid(value) return w.rule.IsValid(value)
} }
// blacklist is a generic rule for blacklisting // excludeList is a generic rule for exclude listing
type blacklist struct { type excludeList struct {
rule rule
} }
// IsValid for whitelist checks if the value is within the whitelist // IsValid for exclude list checks if the value is within the exclude list
func (b blacklist) IsValid(value string) bool { func (b excludeList) IsValid(value string) bool {
return !b.rule.IsValid(value) return !b.rule.IsValid(value)
} }

View File

@ -1,3 +1,4 @@
//go:build !go1.7
// +build !go1.7 // +build !go1.7
package v4 package v4

View File

@ -1,3 +1,4 @@
//go:build go1.7
// +build go1.7 // +build go1.7
package v4 package v4

View File

@ -1,3 +1,4 @@
//go:build go1.5
// +build go1.5 // +build go1.5
package v4 package v4

View File

@ -90,7 +90,7 @@ const (
) )
var ignoredHeaders = rules{ var ignoredHeaders = rules{
blacklist{ excludeList{
mapRule{ mapRule{
authorizationHeader: struct{}{}, authorizationHeader: struct{}{},
"User-Agent": struct{}{}, "User-Agent": struct{}{},
@ -99,9 +99,9 @@ var ignoredHeaders = rules{
}, },
} }
// requiredSignedHeaders is a whitelist for build canonical headers. // requiredSignedHeaders is a allow list for build canonical headers.
var requiredSignedHeaders = rules{ var requiredSignedHeaders = rules{
whitelist{ allowList{
mapRule{ mapRule{
"Cache-Control": struct{}{}, "Cache-Control": struct{}{},
"Content-Disposition": struct{}{}, "Content-Disposition": struct{}{},
@ -145,12 +145,13 @@ var requiredSignedHeaders = rules{
}, },
}, },
patterns{"X-Amz-Meta-"}, patterns{"X-Amz-Meta-"},
patterns{"X-Amz-Object-Lock-"},
} }
// allowedHoisting is a whitelist for build query headers. The boolean value // allowedHoisting is a allow list for build query headers. The boolean value
// represents whether or not it is a pattern. // represents whether or not it is a pattern.
var allowedQueryHoisting = inclusiveRules{ var allowedQueryHoisting = inclusiveRules{
blacklist{requiredSignedHeaders}, excludeList{requiredSignedHeaders},
patterns{"X-Amz-"}, patterns{"X-Amz-"},
} }
@ -417,7 +418,7 @@ var SignRequestHandler = request.NamedHandler{
// request handler should only be used with the SDK's built in service client's // request handler should only be used with the SDK's built in service client's
// API operation requests. // API operation requests.
// //
// This function should not be used on its on its own, but in conjunction with // This function should not be used on its own, but in conjunction with
// an AWS service client's API operation call. To sign a standalone request // an AWS service client's API operation call. To sign a standalone request
// not created by a service client's API operation method use the "Sign" or // not created by a service client's API operation method use the "Sign" or
// "Presign" functions of the "Signer" type. // "Presign" functions of the "Signer" type.

View File

@ -1,3 +1,4 @@
//go:build go1.8
// +build go1.8 // +build go1.8
package aws package aws

View File

@ -1,3 +1,4 @@
//go:build !go1.8
// +build !go1.8 // +build !go1.8
package aws package aws

View File

@ -5,4 +5,4 @@ package aws
const SDKName = "aws-sdk-go" const SDKName = "aws-sdk-go"
// SDKVersion is the version of this SDK // SDKVersion is the version of this SDK
const SDKVersion = "1.38.63" const SDKVersion = "1.40.34"

View File

@ -1,3 +1,4 @@
//go:build !go1.7
// +build !go1.7 // +build !go1.7
package context package context

View File

@ -13,17 +13,30 @@
// } // }
// //
// Below is the BNF that describes this parser // Below is the BNF that describes this parser
// Grammar: // Grammar:
// stmt -> value stmt' // stmt -> section | stmt'
// stmt' -> epsilon | op stmt // stmt' -> epsilon | expr
// value -> number | string | boolean | quoted_string // expr -> value (stmt)* | equal_expr (stmt)*
// equal_expr -> value ( ':' | '=' ) equal_expr'
// equal_expr' -> number | string | quoted_string
// quoted_string -> " quoted_string'
// quoted_string' -> string quoted_string_end
// quoted_string_end -> "
// //
// section -> [ section' // section -> [ section'
// section' -> value section_close // section' -> section_value section_close
// section_close -> ] // section_value -> number | string_subset | boolean | quoted_string_subset
// quoted_string_subset -> " quoted_string_subset'
// quoted_string_subset' -> string_subset quoted_string_end
// quoted_string_subset -> "
// section_close -> ]
// //
// SkipState will skip (NL WS)+ // value -> number | string_subset | boolean
// string -> ? UTF-8 Code-Points except '\n' (U+000A) and '\r\n' (U+000D U+000A) ?
// string_subset -> ? Code-points excepted by <string> grammar except ':' (U+003A), '=' (U+003D), '[' (U+005B), and ']' (U+005D) ?
// //
// comment -> # comment' | ; comment' // SkipState will skip (NL WS)+
// comment' -> epsilon | value //
// comment -> # comment' | ; comment'
// comment' -> epsilon | value
package ini package ini

View File

@ -1,3 +1,4 @@
//go:build gofuzz
// +build gofuzz // +build gofuzz
package ini package ini

View File

@ -5,9 +5,12 @@ import (
"io" "io"
) )
// ParseState represents the current state of the parser.
type ParseState uint
// State enums for the parse table // State enums for the parse table
const ( const (
InvalidState = iota InvalidState ParseState = iota
// stmt -> value stmt' // stmt -> value stmt'
StatementState StatementState
// stmt' -> MarkComplete | op stmt // stmt' -> MarkComplete | op stmt
@ -36,8 +39,8 @@ const (
) )
// parseTable is a state machine to dictate the grammar above. // parseTable is a state machine to dictate the grammar above.
var parseTable = map[ASTKind]map[TokenType]int{ var parseTable = map[ASTKind]map[TokenType]ParseState{
ASTKindStart: map[TokenType]int{ ASTKindStart: {
TokenLit: StatementState, TokenLit: StatementState,
TokenSep: OpenScopeState, TokenSep: OpenScopeState,
TokenWS: SkipTokenState, TokenWS: SkipTokenState,
@ -45,7 +48,7 @@ var parseTable = map[ASTKind]map[TokenType]int{
TokenComment: CommentState, TokenComment: CommentState,
TokenNone: TerminalState, TokenNone: TerminalState,
}, },
ASTKindCommentStatement: map[TokenType]int{ ASTKindCommentStatement: {
TokenLit: StatementState, TokenLit: StatementState,
TokenSep: OpenScopeState, TokenSep: OpenScopeState,
TokenWS: SkipTokenState, TokenWS: SkipTokenState,
@ -53,7 +56,7 @@ var parseTable = map[ASTKind]map[TokenType]int{
TokenComment: CommentState, TokenComment: CommentState,
TokenNone: MarkCompleteState, TokenNone: MarkCompleteState,
}, },
ASTKindExpr: map[TokenType]int{ ASTKindExpr: {
TokenOp: StatementPrimeState, TokenOp: StatementPrimeState,
TokenLit: ValueState, TokenLit: ValueState,
TokenSep: OpenScopeState, TokenSep: OpenScopeState,
@ -62,13 +65,15 @@ var parseTable = map[ASTKind]map[TokenType]int{
TokenComment: CommentState, TokenComment: CommentState,
TokenNone: MarkCompleteState, TokenNone: MarkCompleteState,
}, },
ASTKindEqualExpr: map[TokenType]int{ ASTKindEqualExpr: {
TokenLit: ValueState, TokenLit: ValueState,
TokenWS: SkipTokenState, TokenSep: ValueState,
TokenNL: SkipState, TokenOp: ValueState,
TokenNone: SkipState, TokenWS: SkipTokenState,
TokenNL: SkipState,
TokenNone: SkipState,
}, },
ASTKindStatement: map[TokenType]int{ ASTKindStatement: {
TokenLit: SectionState, TokenLit: SectionState,
TokenSep: CloseScopeState, TokenSep: CloseScopeState,
TokenWS: SkipTokenState, TokenWS: SkipTokenState,
@ -76,9 +81,9 @@ var parseTable = map[ASTKind]map[TokenType]int{
TokenComment: CommentState, TokenComment: CommentState,
TokenNone: MarkCompleteState, TokenNone: MarkCompleteState,
}, },
ASTKindExprStatement: map[TokenType]int{ ASTKindExprStatement: {
TokenLit: ValueState, TokenLit: ValueState,
TokenSep: OpenScopeState, TokenSep: ValueState,
TokenOp: ValueState, TokenOp: ValueState,
TokenWS: ValueState, TokenWS: ValueState,
TokenNL: MarkCompleteState, TokenNL: MarkCompleteState,
@ -86,14 +91,14 @@ var parseTable = map[ASTKind]map[TokenType]int{
TokenNone: TerminalState, TokenNone: TerminalState,
TokenComma: SkipState, TokenComma: SkipState,
}, },
ASTKindSectionStatement: map[TokenType]int{ ASTKindSectionStatement: {
TokenLit: SectionState, TokenLit: SectionState,
TokenOp: SectionState, TokenOp: SectionState,
TokenSep: CloseScopeState, TokenSep: CloseScopeState,
TokenWS: SectionState, TokenWS: SectionState,
TokenNL: SkipTokenState, TokenNL: SkipTokenState,
}, },
ASTKindCompletedSectionStatement: map[TokenType]int{ ASTKindCompletedSectionStatement: {
TokenWS: SkipTokenState, TokenWS: SkipTokenState,
TokenNL: SkipTokenState, TokenNL: SkipTokenState,
TokenLit: StatementState, TokenLit: StatementState,
@ -101,7 +106,7 @@ var parseTable = map[ASTKind]map[TokenType]int{
TokenComment: CommentState, TokenComment: CommentState,
TokenNone: MarkCompleteState, TokenNone: MarkCompleteState,
}, },
ASTKindSkipStatement: map[TokenType]int{ ASTKindSkipStatement: {
TokenLit: StatementState, TokenLit: StatementState,
TokenSep: OpenScopeState, TokenSep: OpenScopeState,
TokenWS: SkipTokenState, TokenWS: SkipTokenState,
@ -205,18 +210,6 @@ loop:
case ValueState: case ValueState:
// ValueState requires the previous state to either be an equal expression // ValueState requires the previous state to either be an equal expression
// or an expression statement. // or an expression statement.
//
// This grammar occurs when the RHS is a number, word, or quoted string.
// equal_expr -> lit op equal_expr'
// equal_expr' -> number | string | quoted_string
// quoted_string -> " quoted_string'
// quoted_string' -> string quoted_string_end
// quoted_string_end -> "
//
// otherwise
// expr_stmt -> equal_expr (expr_stmt')*
// expr_stmt' -> ws S | op S | MarkComplete
// S -> equal_expr' expr_stmt'
switch k.Kind { switch k.Kind {
case ASTKindEqualExpr: case ASTKindEqualExpr:
// assigning a value to some key // assigning a value to some key
@ -243,7 +236,7 @@ loop:
} }
children[len(children)-1] = rhs children[len(children)-1] = rhs
k.SetChildren(children) root.SetChildren(children)
stack.Push(k) stack.Push(k)
} }

View File

@ -50,7 +50,10 @@ func (v *DefaultVisitor) VisitExpr(expr AST) error {
rhs := children[1] rhs := children[1]
if rhs.Root.Type() != TokenLit { // The right-hand value side the equality expression is allowed to contain '[', ']', ':', '=' in the values.
// If the token is not either a literal or one of the token types that identifies those four additional
// tokens then error.
if !(rhs.Root.Type() == TokenLit || rhs.Root.Type() == TokenOp || rhs.Root.Type() == TokenSep) {
return NewParseError("unexpected token type") return NewParseError("unexpected token type")
} }

View File

@ -1,3 +1,4 @@
//go:build !go1.7
// +build !go1.7 // +build !go1.7
package sdkio package sdkio

View File

@ -1,3 +1,4 @@
//go:build go1.7
// +build go1.7 // +build go1.7
package sdkio package sdkio

View File

@ -1,3 +1,4 @@
//go:build go1.10
// +build go1.10 // +build go1.10
package sdkmath package sdkmath

View File

@ -1,3 +1,4 @@
//go:build !go1.10
// +build !go1.10 // +build !go1.10
package sdkmath package sdkmath

View File

@ -1,3 +1,4 @@
//go:build go1.6
// +build go1.6 // +build go1.6
package sdkrand package sdkrand

View File

@ -1,3 +1,4 @@
//go:build !go1.6
// +build !go1.6 // +build !go1.6
package sdkrand package sdkrand

View File

@ -98,7 +98,7 @@ func buildLocationElements(r *request.Request, v reflect.Value, buildGETQuery bo
// Support the ability to customize values to be marshaled as a // Support the ability to customize values to be marshaled as a
// blob even though they were modeled as a string. Required for S3 // blob even though they were modeled as a string. Required for S3
// API operations like SSECustomerKey is modeled as stirng but // API operations like SSECustomerKey is modeled as string but
// required to be base64 encoded in request. // required to be base64 encoded in request.
if field.Tag.Get("marshal-as") == "blob" { if field.Tag.Get("marshal-as") == "blob" {
m = m.Convert(byteSliceType) m = m.Convert(byteSliceType)

View File

@ -1,6 +1,8 @@
package protocol package protocol
import ( import (
"bytes"
"fmt"
"math" "math"
"strconv" "strconv"
"time" "time"
@ -19,13 +21,16 @@ const (
// Output time is intended to not contain decimals // Output time is intended to not contain decimals
const ( const (
// RFC 7231#section-7.1.1.1 timetamp format. e.g Tue, 29 Apr 2014 18:30:38 GMT // RFC 7231#section-7.1.1.1 timetamp format. e.g Tue, 29 Apr 2014 18:30:38 GMT
RFC822TimeFormat = "Mon, 2 Jan 2006 15:04:05 GMT" RFC822TimeFormat = "Mon, 2 Jan 2006 15:04:05 GMT"
rfc822TimeFormatSingleDigitDay = "Mon, _2 Jan 2006 15:04:05 GMT"
rfc822TimeFormatSingleDigitDayTwoDigitYear = "Mon, _2 Jan 06 15:04:05 GMT"
// This format is used for output time without seconds precision // This format is used for output time without seconds precision
RFC822OutputTimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT" RFC822OutputTimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
// RFC3339 a subset of the ISO8601 timestamp format. e.g 2014-04-29T18:30:38Z // RFC3339 a subset of the ISO8601 timestamp format. e.g 2014-04-29T18:30:38Z
ISO8601TimeFormat = "2006-01-02T15:04:05.999999999Z" ISO8601TimeFormat = "2006-01-02T15:04:05.999999999Z"
iso8601TimeFormatNoZ = "2006-01-02T15:04:05.999999999"
// This format is used for output time with fractional second precision up to milliseconds // This format is used for output time with fractional second precision up to milliseconds
ISO8601OutputTimeFormat = "2006-01-02T15:04:05.999999999Z" ISO8601OutputTimeFormat = "2006-01-02T15:04:05.999999999Z"
@ -67,10 +72,21 @@ func FormatTime(name string, t time.Time) string {
// the time if it was able to be parsed, and fails otherwise. // the time if it was able to be parsed, and fails otherwise.
func ParseTime(formatName, value string) (time.Time, error) { func ParseTime(formatName, value string) (time.Time, error) {
switch formatName { switch formatName {
case RFC822TimeFormatName: case RFC822TimeFormatName: // Smithy HTTPDate format
return time.Parse(RFC822TimeFormat, value) return tryParse(value,
case ISO8601TimeFormatName: RFC822TimeFormat,
return time.Parse(ISO8601TimeFormat, value) rfc822TimeFormatSingleDigitDay,
rfc822TimeFormatSingleDigitDayTwoDigitYear,
time.RFC850,
time.ANSIC,
)
case ISO8601TimeFormatName: // Smithy DateTime format
return tryParse(value,
ISO8601TimeFormat,
iso8601TimeFormatNoZ,
time.RFC3339Nano,
time.RFC3339,
)
case UnixTimeFormatName: case UnixTimeFormatName:
v, err := strconv.ParseFloat(value, 64) v, err := strconv.ParseFloat(value, 64)
_, dec := math.Modf(v) _, dec := math.Modf(v)
@ -83,3 +99,36 @@ func ParseTime(formatName, value string) (time.Time, error) {
panic("unknown timestamp format name, " + formatName) panic("unknown timestamp format name, " + formatName)
} }
} }
func tryParse(v string, formats ...string) (time.Time, error) {
var errs parseErrors
for _, f := range formats {
t, err := time.Parse(f, v)
if err != nil {
errs = append(errs, parseError{
Format: f,
Err: err,
})
continue
}
return t, nil
}
return time.Time{}, fmt.Errorf("unable to parse time string, %v", errs)
}
type parseErrors []parseError
func (es parseErrors) Error() string {
var s bytes.Buffer
for _, e := range es {
fmt.Fprintf(&s, "\n * %q: %v", e.Format, e.Err)
}
return "parse errors:" + s.String()
}
type parseError struct {
Format string
Err error
}

Some files were not shown because too many files have changed in this diff Show More