From f9908a496614bfbc05ce45eec5b3e03c0e1f674c Mon Sep 17 00:00:00 2001 From: Oded Viner Date: Sun, 3 Nov 2024 11:32:37 +0200 Subject: [PATCH 1/3] debugging session Signed-off-by: Oded Viner --- e2e/e2e_test.go | 31 + e2e/pod.go | 120 + go.mod | 43 +- go.sum | 91 +- .../Masterminds/semver/v3/.gitignore | 1 + .../Masterminds/semver/v3/.golangci.yml | 27 + .../Masterminds/semver/v3/CHANGELOG.md | 214 + .../Masterminds/semver/v3/LICENSE.txt | 19 + .../github.com/Masterminds/semver/v3/Makefile | 30 + .../Masterminds/semver/v3/README.md | 258 + .../Masterminds/semver/v3/SECURITY.md | 19 + .../Masterminds/semver/v3/collection.go | 24 + .../Masterminds/semver/v3/constraints.go | 594 +++ .../github.com/Masterminds/semver/v3/doc.go | 184 + .../Masterminds/semver/v3/version.go | 639 +++ vendor/github.com/ansel1/merry/Makefile | 5 +- .../github.com/ansel1/merry/chainable_api.go | 14 +- vendor/github.com/ansel1/merry/doc.go | 63 +- vendor/github.com/ansel1/merry/print.go | 28 +- vendor/github.com/ansel1/merry/v2/Makefile | 7 +- vendor/github.com/ansel1/merry/v2/config.go | 36 +- vendor/github.com/ansel1/merry/v2/doc.go | 28 +- vendor/github.com/ansel1/merry/v2/errors.go | 33 +- vendor/github.com/ansel1/merry/v2/impl.go | 22 +- vendor/github.com/ansel1/merry/v2/print.go | 7 +- vendor/github.com/ansel1/merry/v2/wrappers.go | 14 +- .../containernetworking/cni/LICENSE | 201 + .../containernetworking/cni/libcni/api.go | 877 ++++ .../containernetworking/cni/libcni/conf.go | 327 ++ .../cni/libcni/multierror.go | 58 + .../cni/pkg/invoke/args.go | 128 + .../cni/pkg/invoke/delegate.go | 89 + .../cni/pkg/invoke/exec.go | 187 + .../cni/pkg/invoke/find.go | 48 + .../cni/pkg/invoke/os_unix.go} | 17 +- .../cni/pkg/invoke/os_windows.go} | 16 +- .../cni/pkg/invoke/raw_exec.go | 88 + .../cni/pkg/types/020/types.go | 189 + .../cni/pkg/types/040/types.go | 306 ++ .../cni/pkg/types/100/types.go | 352 ++ .../containernetworking/cni/pkg/types/args.go | 122 + .../cni/pkg/types/create/create.go | 59 + .../cni/pkg/types/internal/convert.go | 92 + .../cni/pkg/types/internal/create.go | 66 + .../cni/pkg/types/types.go | 323 ++ .../cni/pkg/utils/utils.go | 82 + .../cni/pkg/version/conf.go | 26 + .../cni/pkg/version/plugin.go | 144 + .../cni/pkg/version/reconcile.go | 49 + .../cni/pkg/version/version.go | 90 + .../emicklei/go-restful/v3/CHANGES.md | 48 +- .../emicklei/go-restful/v3/README.md | 16 +- .../emicklei/go-restful/v3/compress.go | 10 + .../emicklei/go-restful/v3/curly.go | 48 +- .../go-restful/v3/entity_accessors.go | 7 + .../github.com/emicklei/go-restful/v3/json.go | 11 - .../emicklei/go-restful/v3/jsoniter.go | 12 - .../emicklei/go-restful/v3/jsr311.go | 2 +- vendor/github.com/fatih/color/LICENSE.md | 20 + vendor/github.com/fatih/color/README.md | 176 + vendor/github.com/fatih/color/color.go | 655 +++ .../github.com/fatih/color/color_windows.go | 19 + vendor/github.com/fatih/color/doc.go | 134 + vendor/github.com/gemalto/flume/.golangci.yml | 5 +- vendor/github.com/gemalto/flume/Makefile | 3 +- vendor/github.com/gemalto/flume/config.go | 27 +- .../gemalto/flume/console_encoder.go | 3 +- vendor/github.com/gemalto/flume/core.go | 3 +- vendor/github.com/gemalto/flume/doc.go | 152 +- vendor/github.com/gemalto/flume/factory.go | 28 +- .../github.com/gemalto/flume/logger_writer.go | 12 +- .../github.com/gemalto/flume/ltsv_encoder.go | 3 +- .../go-openapi/jsonpointer/.golangci.yml | 61 + .../go-openapi/jsonpointer/README.md | 8 +- .../go-openapi/jsonpointer/pointer.go | 191 +- .../go-openapi/jsonreference/.golangci.yml | 57 +- .../go-openapi/jsonreference/README.md | 14 +- vendor/github.com/go-openapi/swag/.gitignore | 1 + .../github.com/go-openapi/swag/.golangci.yml | 54 +- .../github.com/go-openapi/swag/BENCHMARK.md | 52 + vendor/github.com/go-openapi/swag/README.md | 8 +- .../go-openapi/swag/initialism_index.go | 202 + vendor/github.com/go-openapi/swag/loading.go | 105 +- .../github.com/go-openapi/swag/name_lexem.go | 70 +- .../github.com/go-openapi/swag/post_go19.go | 68 - vendor/github.com/go-openapi/swag/pre_go19.go | 70 - vendor/github.com/go-openapi/swag/split.go | 470 +- .../go-openapi/swag/string_bytes.go | 8 + vendor/github.com/go-openapi/swag/util.go | 210 +- vendor/github.com/go-openapi/swag/yaml.go | 39 +- vendor/github.com/golang/mock/AUTHORS | 12 + vendor/github.com/golang/mock/CONTRIBUTORS | 37 + vendor/github.com/golang/mock/LICENSE | 202 + vendor/github.com/golang/mock/gomock/call.go | 445 ++ .../github.com/golang/mock/gomock/callset.go | 113 + .../golang/mock/gomock/controller.go | 337 ++ .../github.com/golang/mock/gomock/matchers.go | 346 ++ .../go-secure-stdlib/parseutil/LICENSE | 3 +- .../go-secure-stdlib/parseutil/parsepath.go | 30 +- .../go-secure-stdlib/parseutil/parseutil.go | 3 + .../github.com/hashicorp/go-sockaddr/LICENSE | 2 + .../hashicorp/go-sockaddr/ifaddrs.go | 25 +- .../hashicorp/go-sockaddr/route_info.go | 11 + .../hashicorp/go-sockaddr/route_info_bsd.go | 7 +- .../go-sockaddr/route_info_default.go | 17 +- .../hashicorp/go-sockaddr/route_info_linux.go | 5 +- .../go-sockaddr/route_info_solaris.go | 4 - .../go-sockaddr/route_info_test_windows.go | 25 + .../go-sockaddr/route_info_windows.go | 34 +- .../hashicorp/go-sockaddr/unixsock.go | 13 + .../hashicorp/vault/api/auth/approle/LICENSE | 45 +- .../vault/api/auth/kubernetes/LICENSE | 45 +- .../github.com/imdario/mergo/CONTRIBUTING.md | 112 + vendor/github.com/imdario/mergo/README.md | 25 +- vendor/github.com/imdario/mergo/SECURITY.md | 14 + vendor/github.com/imdario/mergo/map.go | 6 +- vendor/github.com/imdario/mergo/merge.go | 59 +- vendor/github.com/imdario/mergo/mergo.go | 11 +- .../LICENSE | 201 + .../NOTICE | 1 + .../pkg/apis/k8s.cni.cncf.io/register.go | 5 + .../pkg/apis/k8s.cni.cncf.io/v1/doc.go | 5 + .../pkg/apis/k8s.cni.cncf.io/v1/register.go | 41 + .../pkg/apis/k8s.cni.cncf.io/v1/types.go | 202 + .../v1/zz_generated.deepcopy.go | 202 + .../pkg/utils/cniconfig.go | 237 + .../pkg/utils/net-attach-def.go | 268 + .../lib-bucket-provisioner/LICENSE | 201 + .../pkg/apis/objectbucket.io/register.go | 19 + .../pkg/apis/objectbucket.io/v1alpha1/doc.go | 20 + .../v1alpha1/objectbucket_types.go | 161 + .../v1alpha1/objectbucketclaim_types.go | 105 + .../apis/objectbucket.io/v1alpha1/register.go | 64 + .../v1alpha1/zz_generated.deepcopy.go | 335 ++ .../secrets/vault/utils/utils.go | 1 + .../libopenstorage/secrets/vault/vault.go | 106 +- ...0000_03_security-openshift_01_scc.crd.yaml | 592 ++- .../github.com/rook/kubectl-rook-ceph/LICENSE | 201 + .../kubectl-rook-ceph/pkg/k8sutil/context.go | 39 + .../kubectl-rook-ceph/pkg/k8sutil/dynamic.go | 146 + .../pkg/k8sutil/interface.go | 33 + .../kubectl-rook-ceph/pkg/k8sutil/k8sutil.go | 124 + .../kubectl-rook-ceph/pkg/k8sutil/mocks.go | 110 + .../rook/kubectl-rook-ceph/pkg/logging/log.go | 56 + vendor/github.com/rook/rook/LICENSE | 201 + vendor/github.com/rook/rook/pkg/apis/LICENSE | 201 + .../rook/pkg/apis/ceph.rook.io/register.go | 5 + .../pkg/apis/ceph.rook.io/v1/annotations.go | 108 + .../rook/pkg/apis/ceph.rook.io/v1/cleanup.go | 47 + .../rook/pkg/apis/ceph.rook.io/v1/cluster.go | 46 + .../rook/rook/pkg/apis/ceph.rook.io/v1/doc.go | 21 + .../pkg/apis/ceph.rook.io/v1/filesystem.go | 21 + .../rook/pkg/apis/ceph.rook.io/v1/keys.go | 34 + .../rook/pkg/apis/ceph.rook.io/v1/labels.go | 131 + .../rook/pkg/apis/ceph.rook.io/v1/mirror.go | 26 + .../rook/pkg/apis/ceph.rook.io/v1/network.go | 175 + .../rook/rook/pkg/apis/ceph.rook.io/v1/nfs.go | 105 + .../rook/pkg/apis/ceph.rook.io/v1/object.go | 116 + .../pkg/apis/ceph.rook.io/v1/placement.go | 147 + .../rook/pkg/apis/ceph.rook.io/v1/pool.go | 101 + .../apis/ceph.rook.io/v1/priorityclasses.go | 73 + .../rook/pkg/apis/ceph.rook.io/v1/register.go | 102 + .../pkg/apis/ceph.rook.io/v1/resources.go | 106 + .../rook/rook/pkg/apis/ceph.rook.io/v1/scc.go | 81 + .../rook/pkg/apis/ceph.rook.io/v1/security.go | 78 + .../rook/pkg/apis/ceph.rook.io/v1/status.go | 74 + .../rook/pkg/apis/ceph.rook.io/v1/storage.go | 198 + .../rook/pkg/apis/ceph.rook.io/v1/topic.go | 84 + .../rook/pkg/apis/ceph.rook.io/v1/types.go | 3075 +++++++++++ .../rook/pkg/apis/ceph.rook.io/v1/volume.go | 50 + .../ceph.rook.io/v1/zz_generated.deepcopy.go | 4487 +++++++++++++++++ .../client/clientset/versioned/clientset.go | 97 + .../pkg/client/clientset/versioned/doc.go | 20 + .../client/clientset/versioned/scheme/doc.go | 20 + .../clientset/versioned/scheme/register.go | 56 + .../ceph.rook.io/v1/ceph.rook.io_client.go | 169 + .../typed/ceph.rook.io/v1/cephblockpool.go | 178 + .../v1/cephblockpoolradosnamespace.go | 178 + .../ceph.rook.io/v1/cephbucketnotification.go | 178 + .../typed/ceph.rook.io/v1/cephbuckettopic.go | 178 + .../typed/ceph.rook.io/v1/cephclient.go | 178 + .../typed/ceph.rook.io/v1/cephcluster.go | 178 + .../typed/ceph.rook.io/v1/cephcosidriver.go | 178 + .../typed/ceph.rook.io/v1/cephfilesystem.go | 178 + .../ceph.rook.io/v1/cephfilesystemmirror.go | 178 + .../v1/cephfilesystemsubvolumegroup.go | 178 + .../typed/ceph.rook.io/v1/cephnfs.go | 178 + .../typed/ceph.rook.io/v1/cephobjectrealm.go | 178 + .../typed/ceph.rook.io/v1/cephobjectstore.go | 178 + .../ceph.rook.io/v1/cephobjectstoreuser.go | 178 + .../typed/ceph.rook.io/v1/cephobjectzone.go | 178 + .../ceph.rook.io/v1/cephobjectzonegroup.go | 178 + .../typed/ceph.rook.io/v1/cephrbdmirror.go | 178 + .../versioned/typed/ceph.rook.io/v1/doc.go | 20 + .../ceph.rook.io/v1/generated_expansion.go | 53 + vendor/go.uber.org/zap/.golangci.yml | 2 +- vendor/go.uber.org/zap/.readme.tmpl | 11 +- vendor/go.uber.org/zap/CHANGELOG.md | 54 +- .../go.uber.org/zap/{LICENSE.txt => LICENSE} | 0 vendor/go.uber.org/zap/README.md | 67 +- vendor/go.uber.org/zap/buffer/buffer.go | 2 +- vendor/go.uber.org/zap/field.go | 2 + vendor/go.uber.org/zap/logger.go | 39 +- vendor/go.uber.org/zap/options.go | 15 + vendor/go.uber.org/zap/sugar.go | 39 + .../zap/zapcore/console_encoder.go | 2 +- vendor/go.uber.org/zap/zapcore/encoder.go | 15 + vendor/go.uber.org/zap/zapcore/field.go | 2 +- .../go.uber.org/zap/zapcore/json_encoder.go | 2 +- vendor/go.uber.org/zap/zapgrpc/zapgrpc.go | 18 +- vendor/modules.txt | 91 +- 211 files changed, 27405 insertions(+), 1342 deletions(-) create mode 100644 vendor/github.com/Masterminds/semver/v3/.gitignore create mode 100644 vendor/github.com/Masterminds/semver/v3/.golangci.yml create mode 100644 vendor/github.com/Masterminds/semver/v3/CHANGELOG.md create mode 100644 vendor/github.com/Masterminds/semver/v3/LICENSE.txt create mode 100644 vendor/github.com/Masterminds/semver/v3/Makefile create mode 100644 vendor/github.com/Masterminds/semver/v3/README.md create mode 100644 vendor/github.com/Masterminds/semver/v3/SECURITY.md create mode 100644 vendor/github.com/Masterminds/semver/v3/collection.go create mode 100644 vendor/github.com/Masterminds/semver/v3/constraints.go create mode 100644 vendor/github.com/Masterminds/semver/v3/doc.go create mode 100644 vendor/github.com/Masterminds/semver/v3/version.go create mode 100644 vendor/github.com/containernetworking/cni/LICENSE create mode 100644 vendor/github.com/containernetworking/cni/libcni/api.go create mode 100644 vendor/github.com/containernetworking/cni/libcni/conf.go create mode 100644 vendor/github.com/containernetworking/cni/libcni/multierror.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/invoke/args.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/invoke/exec.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/invoke/find.go rename vendor/github.com/{go-openapi/swag/pre_go18.go => containernetworking/cni/pkg/invoke/os_unix.go} (60%) rename vendor/github.com/{go-openapi/swag/post_go18.go => containernetworking/cni/pkg/invoke/os_windows.go} (68%) create mode 100644 vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/types/020/types.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/types/040/types.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/types/100/types.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/types/args.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/types/create/create.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/types/internal/convert.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/types/internal/create.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/types/types.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/utils/utils.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/version/conf.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/version/plugin.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/version/reconcile.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/version/version.go delete mode 100644 vendor/github.com/emicklei/go-restful/v3/json.go delete mode 100644 vendor/github.com/emicklei/go-restful/v3/jsoniter.go create mode 100644 vendor/github.com/fatih/color/LICENSE.md create mode 100644 vendor/github.com/fatih/color/README.md create mode 100644 vendor/github.com/fatih/color/color.go create mode 100644 vendor/github.com/fatih/color/color_windows.go create mode 100644 vendor/github.com/fatih/color/doc.go create mode 100644 vendor/github.com/go-openapi/jsonpointer/.golangci.yml create mode 100644 vendor/github.com/go-openapi/swag/BENCHMARK.md create mode 100644 vendor/github.com/go-openapi/swag/initialism_index.go delete mode 100644 vendor/github.com/go-openapi/swag/post_go19.go delete mode 100644 vendor/github.com/go-openapi/swag/pre_go19.go create mode 100644 vendor/github.com/go-openapi/swag/string_bytes.go create mode 100644 vendor/github.com/golang/mock/AUTHORS create mode 100644 vendor/github.com/golang/mock/CONTRIBUTORS create mode 100644 vendor/github.com/golang/mock/LICENSE create mode 100644 vendor/github.com/golang/mock/gomock/call.go create mode 100644 vendor/github.com/golang/mock/gomock/callset.go create mode 100644 vendor/github.com/golang/mock/gomock/controller.go create mode 100644 vendor/github.com/golang/mock/gomock/matchers.go create mode 100644 vendor/github.com/hashicorp/go-sockaddr/route_info_test_windows.go create mode 100644 vendor/github.com/imdario/mergo/CONTRIBUTING.md create mode 100644 vendor/github.com/imdario/mergo/SECURITY.md create mode 100644 vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/LICENSE create mode 100644 vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/NOTICE create mode 100644 vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/register.go create mode 100644 vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/doc.go create mode 100644 vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/register.go create mode 100644 vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go create mode 100644 vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/zz_generated.deepcopy.go create mode 100644 vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/cniconfig.go create mode 100644 vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go create mode 100644 vendor/github.com/kube-object-storage/lib-bucket-provisioner/LICENSE create mode 100644 vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/register.go create mode 100644 vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/doc.go create mode 100644 vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/objectbucket_types.go create mode 100644 vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/objectbucketclaim_types.go create mode 100644 vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/register.go create mode 100644 vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/zz_generated.deepcopy.go create mode 100644 vendor/github.com/rook/kubectl-rook-ceph/LICENSE create mode 100644 vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/context.go create mode 100644 vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/dynamic.go create mode 100644 vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/interface.go create mode 100644 vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/k8sutil.go create mode 100644 vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/mocks.go create mode 100644 vendor/github.com/rook/kubectl-rook-ceph/pkg/logging/log.go create mode 100644 vendor/github.com/rook/rook/LICENSE create mode 100644 vendor/github.com/rook/rook/pkg/apis/LICENSE create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/register.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/annotations.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/cleanup.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/cluster.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/doc.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/filesystem.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/keys.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/labels.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/mirror.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/network.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/nfs.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/object.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/placement.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/pool.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/priorityclasses.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/register.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/resources.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/scc.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/security.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/status.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/storage.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/topic.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/types.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/volume.go create mode 100644 vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/clientset.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/doc.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/scheme/doc.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/scheme/register.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/ceph.rook.io_client.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephblockpool.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephblockpoolradosnamespace.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephbucketnotification.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephbuckettopic.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephclient.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephcluster.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephcosidriver.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephfilesystem.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephfilesystemmirror.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephfilesystemsubvolumegroup.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephnfs.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectrealm.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectstore.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectstoreuser.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectzone.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectzonegroup.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephrbdmirror.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/doc.go create mode 100644 vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/generated_expansion.go rename vendor/go.uber.org/zap/{LICENSE.txt => LICENSE} (100%) diff --git a/e2e/e2e_test.go b/e2e/e2e_test.go index e4538788aeb..327a7df9a2a 100644 --- a/e2e/e2e_test.go +++ b/e2e/e2e_test.go @@ -17,6 +17,9 @@ limitations under the License. package e2e import ( + "bytes" + "context" + "encoding/json" "flag" "fmt" "log" @@ -70,11 +73,39 @@ func setDefaultKubeconfig() { } func TestE2E(t *testing.T) { + f := framework.NewDefaultFramework("some tests") + ctx := context.TODO() + clientsets := getClientsets(ctx) + var stdout, stderr bytes.Buffer + fruits := []string{"health"} + + err := execCmdInPod(ctx, clientsets, "ceph", "rook-ceph-tools-68bf47bc65-57pmq", "rook-ceph-tools", "rook-ceph", "rook-ceph", fruits, &stdout, &stderr, true) + if err != nil { + fmt.Println(err) + } + var imgInfos []string + err = json.Unmarshal(stdout.Bytes(), &imgInfos) + validateRBDImageCount(f, 1, "a") t.Parallel() RegisterFailHandler(Fail) RunSpecs(t, "E2e Suite") } +func TestDebug(t *testing.T) { + f := framework.NewDefaultFramework("some tests") + ctx := context.TODO() + clientsets := getClientsets(ctx) + var stdout, stderr bytes.Buffer + fruits := []string{"health"} + err := execCmdInPod(ctx, clientsets, "ceph", "rook-ceph-tools-68bf47bc65-57pmq", "rook-ceph-tools", "rook-ceph", "rook-ceph", fruits, &stdout, &stderr, true) + if err != nil { + fmt.Println(err) + } + var imgInfos []string + err = json.Unmarshal(stdout.Bytes(), &imgInfos) + validateRBDImageCount(f, 1, "a") +} + func handleFlags() { config.CopyFlags(config.Flags, flag.CommandLine) framework.RegisterCommonFlags(flag.CommandLine) diff --git a/e2e/pod.go b/e2e/pod.go index 4113e4334dc..99fc74c3d1b 100644 --- a/e2e/pod.go +++ b/e2e/pod.go @@ -20,6 +20,13 @@ import ( "context" "errors" "fmt" + "github.com/rook/kubectl-rook-ceph/pkg/k8sutil" + rookclient "github.com/rook/rook/pkg/client/clientset/versioned" + "io" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/tools/remotecommand" + "os" "regexp" "strings" "time" @@ -28,7 +35,9 @@ import ( apierrs "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" + k8s "k8s.io/client-go/kubernetes" "k8s.io/kubernetes/pkg/client/conditions" "k8s.io/kubernetes/test/e2e/framework" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" @@ -723,3 +732,114 @@ func verifyReadAffinity( return nil } + +func getClientsets(ctx context.Context) *k8sutil.Clientsets { + var err error + var kubeContext string + clientsets := &k8sutil.Clientsets{} + + congfigOverride := &clientcmd.ConfigOverrides{} + if kubeContext != "" { + congfigOverride = &clientcmd.ConfigOverrides{CurrentContext: kubeContext} + } + + // 1. Create Kubernetes Client + kubeconfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( + clientcmd.NewDefaultClientConfigLoadingRules(), + congfigOverride, + ) + + clientsets.KubeConfig, err = kubeconfig.ClientConfig() + if err != nil { + fmt.Println(err) + } + + clientsets.Rook, err = rookclient.NewForConfig(clientsets.KubeConfig) + if err != nil { + fmt.Println(err) + } + + clientsets.Kube, err = k8s.NewForConfig(clientsets.KubeConfig) + if err != nil { + fmt.Println(err) + } + + clientsets.Dynamic, err = dynamic.NewForConfig(clientsets.KubeConfig) + if err != nil { + fmt.Println(err) + } + + return clientsets +} + +// execCmdInPod exec command on specific pod and wait the command's output. +func execCmdInPod(ctx context.Context, clientsets *k8sutil.Clientsets, + command, podName, containerName, podNamespace, clusterNamespace string, + args []string, stdout, stderr io.Writer, returnOutput bool) error { + + if len(args) < 1 { + return fmt.Errorf("no arg passed to exec with %q command", command) + } + + cmd := []string{} + cmd = append(cmd, command) + cmd = append(cmd, args...) + + if containerName == "rook-ceph-tools" { + cmd = append(cmd, "--connect-timeout=10") + } else if cmd[0] == "ceph" { + if len(cmd) > 1 && cmd[1] == "daemon" { + cmd = append(cmd, "--connect-timeout=10") + } else { + cmd = append(cmd, "--connect-timeout=10", fmt.Sprintf("--conf=/var/lib/rook/%s/%s.config", clusterNamespace, clusterNamespace)) + } + } else if cmd[0] == "rbd" { + cmd = append(cmd, fmt.Sprintf("--conf=/var/lib/rook/%s/%s.config", clusterNamespace, clusterNamespace)) + } else if cmd[0] == "rados" { + cmd = append(cmd, fmt.Sprintf("--conf=/var/lib/rook/%s/%s.config", clusterNamespace, clusterNamespace)) + } else if cmd[0] == "radosgw-admin" { + cmd = append(cmd, fmt.Sprintf("--conf=/var/lib/rook/%s/%s.config", clusterNamespace, clusterNamespace)) + } + + // Prepare the API URL used to execute another process within the Pod. In + // this case, we'll run a remote shell. + req := clientsets.Kube.CoreV1().RESTClient(). + Post(). + Namespace(podNamespace). + Resource("pods"). + Name(podName). + SubResource("exec"). + VersionedParams(&v1.PodExecOptions{ + Container: containerName, + Command: cmd, + Stdout: true, + Stderr: true, + TTY: false, + }, scheme.ParameterCodec) + + exec, err := remotecommand.NewSPDYExecutor(clientsets.KubeConfig, "POST", req.URL()) + if err != nil { + return fmt.Errorf("failed to create SPDYExecutor. %w", err) + } + + // returnOutput is true, the command's output will be print on shell directly with os.Stdout or os.Stderr + if !returnOutput { + // Connect this process' std{in,out,err} to the remote shell process. + err = exec.StreamWithContext(ctx, remotecommand.StreamOptions{ + Stdout: os.Stdout, + Stderr: os.Stderr, + Tty: false, + }) + } else { + // Connect this process' std{in,out,err} to the remote shell process. + err = exec.StreamWithContext(ctx, remotecommand.StreamOptions{ + Stdout: stdout, + Stderr: stderr, + Tty: false, + }) + } + if err != nil { + return fmt.Errorf("failed to run command. %w", err) + } + return nil +} diff --git a/go.mod b/go.mod index 313262055af..9660073ab85 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/IBM/keyprotect-go-client v0.15.1 github.com/aws/aws-sdk-go v1.55.5 github.com/aws/aws-sdk-go-v2/service/sts v1.32.3 - github.com/ceph/ceph-csi/api v0.0.0-00010101000000-000000000000 + github.com/ceph/ceph-csi/api v0.0.0-20231227104434-06f9a98b7a83 github.com/ceph/go-ceph v0.30.0 github.com/container-storage-interface/spec v1.10.0 github.com/csi-addons/spec v0.2.1-0.20240730084235-3958a5b17d24 @@ -19,7 +19,7 @@ require ( github.com/hashicorp/vault/api v1.15.0 github.com/kubernetes-csi/csi-lib-utils v0.19.0 github.com/kubernetes-csi/external-snapshotter/client/v8 v8.0.0 - github.com/libopenstorage/secrets v0.0.0-20231011182615-5f4b25ceede1 + github.com/libopenstorage/secrets v0.0.0-20240416031220-a17cf7f72c6c github.com/onsi/ginkgo/v2 v2.20.2 github.com/onsi/gomega v1.34.2 github.com/pkg/xattr v0.4.10 @@ -48,6 +48,8 @@ require ( require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.2.0 + github.com/rook/kubectl-rook-ceph v0.9.2 + github.com/rook/rook v1.15.4 ) require ( @@ -55,9 +57,10 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect - github.com/ansel1/merry v1.6.2 // indirect - github.com/ansel1/merry/v2 v2.0.1 // indirect + github.com/ansel1/merry v1.8.0 // indirect + github.com/ansel1/merry/v2 v2.2.0 // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect github.com/aws/aws-sdk-go-v2 v1.32.3 // indirect @@ -70,27 +73,30 @@ require ( github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/containernetworking/cni v1.2.0-rc1 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/distribution/reference v0.5.0 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect + github.com/fatih/color v1.17.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/gemalto/flume v0.13.0 // indirect + github.com/gemalto/flume v0.13.1 // indirect github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect github.com/go-jose/go-jose/v4 v4.0.1 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/mock v1.6.0 // indirect github.com/google/cel-go v0.20.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect @@ -103,18 +109,20 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect - github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8 // indirect github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect - github.com/hashicorp/go-sockaddr v1.0.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.6 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hashicorp/vault/api/auth/approle v0.5.0 // indirect - github.com/hashicorp/vault/api/auth/kubernetes v0.5.0 // indirect - github.com/imdario/mergo v0.3.13 // indirect + github.com/hashicorp/vault/api/auth/approle v0.6.0 // indirect + github.com/hashicorp/vault/api/auth/kubernetes v0.6.0 // indirect + github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.0 // indirect github.com/klauspost/compress v1.17.9 // indirect + github.com/kube-object-storage/lib-bucket-provisioner v0.0.0-20221122204822-d1a8c34382f1 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -130,13 +138,14 @@ require ( github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/selinux v1.11.0 // indirect - github.com/openshift/api v0.0.0-20240115183315-0793e918179d // indirect + github.com/openshift/api v0.0.0-20240301093301-ce10821dc999 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect + github.com/rook/rook/pkg/apis v0.0.0-20231204200402-5287527732f7 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/cobra v1.8.1 // indirect @@ -156,7 +165,7 @@ require ( go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect + go.uber.org/zap v1.27.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/oauth2 v0.22.0 // indirect golang.org/x/sync v0.8.0 // indirect @@ -178,7 +187,7 @@ require ( k8s.io/component-helpers v0.31.1 // indirect k8s.io/controller-manager v0.31.1 // indirect k8s.io/kms v0.31.1 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + k8s.io/kube-openapi v0.0.0-20240620174524-b456828f718b // indirect k8s.io/kubectl v0.0.0 // indirect k8s.io/kubelet v0.0.0 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect diff --git a/go.sum b/go.sum index 05fcc4ea98e..e939065b452 100644 --- a/go.sum +++ b/go.sum @@ -1354,6 +1354,8 @@ github.com/IBM/keyprotect-go-client v0.5.1/go.mod h1:5TwDM/4FRJq1ZOlwQL1xFahLWQ3 github.com/IBM/keyprotect-go-client v0.15.1 h1:m4qzqF5zOumRxKZ8s7vtK7A/UV/D278L8xpRG+WgT0s= github.com/IBM/keyprotect-go-client v0.15.1/go.mod h1:asXtHwL/4uCHA221Vd/7SkXEi2pcRHDzPyyksc1DthE= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -1385,11 +1387,11 @@ github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHG github.com/ansel1/merry v1.5.0/go.mod h1:wUy/yW0JX0ix9GYvUbciq+bi3jW/vlKPlbpI7qdZpOw= github.com/ansel1/merry v1.5.1/go.mod h1:wUy/yW0JX0ix9GYvUbciq+bi3jW/vlKPlbpI7qdZpOw= github.com/ansel1/merry v1.6.1/go.mod h1:ioJjPJ/IsjxH+cC0lpf5TmbKnbcGa9qTk0fDbeRfnGQ= -github.com/ansel1/merry v1.6.2 h1:0xr40haRrfVzmOH/JVOu7KOKGEI1c/7q5EmgTEbn+Ng= -github.com/ansel1/merry v1.6.2/go.mod h1:pAcMW+2uxIgpzEON021vMtFsrymREY6faJWiiz1QGVQ= +github.com/ansel1/merry v1.8.0 h1:3RddCV1ubXegKphsodbkmZ4QuROep/ZaPCuwlKuCfFg= +github.com/ansel1/merry v1.8.0/go.mod h1:wJVu1mHEtEUWq5zTTX9RiWjcE+xL8y7BGYl2VTYdP7M= github.com/ansel1/merry/v2 v2.0.0-beta.10/go.mod h1:OUvUYh4KLVhf3+sR9Hk8QxCukijznkpheEd837b7vLg= -github.com/ansel1/merry/v2 v2.0.1 h1:WeiKZdslHPAPFYxTtgX7clC2Vh75NCoWs5OjCZbIA0A= -github.com/ansel1/merry/v2 v2.0.1/go.mod h1:dD5OhpiPrVkvgseRYd+xgYlx7s6ytU3v9BTTJlDA7FM= +github.com/ansel1/merry/v2 v2.2.0 h1:UozCy11F6igadv9XQgOBFr9xguUWJGvdWwQydh0s7pc= +github.com/ansel1/merry/v2 v2.2.0/go.mod h1:nrJgBqVO1A8RnUXma1T8slt3wznjZcfbD8HzXaCoLwM= github.com/ansel1/vespucci/v4 v4.1.1/go.mod h1:zzdrO4IgBfgcGMbGTk/qNGL8JPslmW3nPpcBHKReFYY= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= @@ -1488,6 +1490,8 @@ github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1Ig github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/container-storage-interface/spec v1.10.0 h1:YkzWPV39x+ZMTa6Ax2czJLLwpryrQ+dPesB34mrRMXA= github.com/container-storage-interface/spec v1.10.0/go.mod h1:DtUvaQszPml1YJfIK7c00mlv6/g4wNMLanLgiUbKFRI= +github.com/containernetworking/cni v1.2.0-rc1 h1:AKI3+pXtgY4PDLN9+50o9IaywWVuey0Jkw3Lvzp0HCY= +github.com/containernetworking/cni v1.2.0-rc1/go.mod h1:Lt0TQcZQVDju64fYxUhDziTgXCDe3Olzi9I4zZJLWHg= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= @@ -1525,8 +1529,9 @@ 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/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= +github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= 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= @@ -1551,16 +1556,17 @@ github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7 github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= -github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= +github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= @@ -1571,8 +1577,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gemalto/flume v0.13.0 h1:EEeQvAxyFys3BH8IxEU7ZpM6Kr1sYn20HuZq6dgyMR8= -github.com/gemalto/flume v0.13.0/go.mod h1:3iOEZiK/HD8SnFTqHCQoOHQKaHlBY0b6z55P8SLaOzk= +github.com/gemalto/flume v0.13.1 h1:wB9T4HP3D+3FRTymi8BzdDHkdTY8UbzH2eVSfYHmLxQ= +github.com/gemalto/flume v0.13.1/go.mod h1:CCm9802zdB4Sy7Jx8dpHaFJjd4fF/nVfCIWBS4f8k9g= github.com/gemalto/kmip-go v0.0.10 h1:jAAZejUdRrspKigLoA62MTmIj0T7DDDOzdxHi1cDjoU= github.com/gemalto/kmip-go v0.0.10/go.mod h1:7XtwjeX7tNQt/FoDZDWXjYOkyV26ZQF1fKFBeR3mCwY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -1580,8 +1586,8 @@ github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ER github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.1.1/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs= -github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= -github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= +github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= @@ -1591,6 +1597,7 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= +github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U= github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -1621,17 +1628,20 @@ github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -1691,6 +1701,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -1718,8 +1729,9 @@ github.com/gomodules/jsonpatch/v2 v2.2.0 h1:QBjDK/nX43P4z/Os3gnk8VeFdLDgBuMns1Wl github.com/gomodules/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= +github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84= github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= @@ -1868,14 +1880,16 @@ github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFO github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8 h1:iBt4Ew4XEGLfh6/bPk4rSYmuZJGizr6/x/AEizP0CQc= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8/go.mod h1:aiJI+PIApBRQG7FZTEBx5GiiX+HbOHilUdNxUZi4eV0= github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-sockaddr v1.0.6 h1:RSG8rKU28VTUTvEKghe5gIhIQpv8evvNpnDEyqO4u9I= +github.com/hashicorp/go-sockaddr v1.0.6/go.mod h1:uoUUmtwU7n9Dv3O4SNLeFvg0SxQ3lyjsj6+CCykpaxI= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -1891,12 +1905,15 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/vault/api v1.10.0/go.mod h1:jo5Y/ET+hNyz+JnKDt8XLAdKs+AM0G5W0Vp1IrFI8N8= +github.com/hashicorp/vault/api v1.12.0/go.mod h1:si+lJCYO7oGkIoNPAN8j3azBLTn9SjMGS+jFaHd1Cck= github.com/hashicorp/vault/api v1.15.0 h1:O24FYQCWwhwKnF7CuSqP30S51rTV7vz1iACXE/pj5DA= github.com/hashicorp/vault/api v1.15.0/go.mod h1:+5YTO09JGn0u+b6ySD/LLVf8WkJCPLAL2Vkmrn2+CM8= -github.com/hashicorp/vault/api/auth/approle v0.5.0 h1:a1TK6VGwYqSAfkmX4y4dJ4WBxMU5dStIZqScW4EPXR8= github.com/hashicorp/vault/api/auth/approle v0.5.0/go.mod h1:CHOQIA1AZACfjTzHggmyfiOZ+xCSKNRFqe48FTCzH0k= -github.com/hashicorp/vault/api/auth/kubernetes v0.5.0 h1:CXO0fD7M3iCGovP/UApeHhPcH4paDFKcu7AjEXi94rI= +github.com/hashicorp/vault/api/auth/approle v0.6.0 h1:ELfFFQlTM/e97WJKu1HvNFa7lQ3tlTwwzrR1NJE1V7Y= +github.com/hashicorp/vault/api/auth/approle v0.6.0/go.mod h1:CCoIl1xBC3lAWpd1HV+0ovk76Z8b8Mdepyk21h3pGk0= github.com/hashicorp/vault/api/auth/kubernetes v0.5.0/go.mod h1:afrElBIO9Q4sHFVuVWgNevG4uAs1bT2AZFA9aEiI608= +github.com/hashicorp/vault/api/auth/kubernetes v0.6.0 h1:K8sKGhtTAqGKfzaaYvUSIOAqTOIn3Gk1EsCEAMzZHtM= +github.com/hashicorp/vault/api/auth/kubernetes v0.6.0/go.mod h1:Htwcjez5J9PwAHaZ1EYMBlgGq3/in5ajUV4+WCPihPE= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= @@ -1907,8 +1924,9 @@ github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= @@ -1938,6 +1956,8 @@ github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+ github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/k0kubun/pp v2.3.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg= +github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.0 h1:47q2PIbDYHmOaqLxgGnvpLq96v9UKDsJfNW6j/KbfpQ= +github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.0/go.mod h1:KDX0bPKeuhMakcNzLf2sWXKPNZ30wH01bsY/KJZLxFY= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs= github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw= @@ -1967,6 +1987,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kube-object-storage/lib-bucket-provisioner v0.0.0-20221122204822-d1a8c34382f1 h1:dQEHhTfi+bSIOSViQrKY9PqJvZenD6tFz+3lPzux58o= +github.com/kube-object-storage/lib-bucket-provisioner v0.0.0-20221122204822-d1a8c34382f1/go.mod h1:my+EVjOJLeQ9lUR9uVkxRvNNkhO2saSGIgzV8GZT9HY= github.com/kubernetes-csi/csi-lib-utils v0.19.0 h1:3sT8mL9+St2acyrEtuR7CQ5L78GR4lgsb+sfon9tGfA= github.com/kubernetes-csi/csi-lib-utils v0.19.0/go.mod h1:lBuMKvoyd8c3EG+itmnVWApLDHnLkU7ibxxZSPuOw0M= github.com/kubernetes-csi/external-snapshotter/client/v4 v4.0.0/go.mod h1:YBCo4DoEeDndqvAn6eeu0vWM7QdXmHEeI9cFWplmBys= @@ -1979,8 +2001,8 @@ github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgx github.com/libopenstorage/autopilot-api v0.6.1-0.20210128210103-5fbb67948648/go.mod h1:6JLrPbR3ZJQFbUY/+QJMl/aF00YdIrLf8/GWAplgvJs= github.com/libopenstorage/openstorage v8.0.0+incompatible/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc= github.com/libopenstorage/operator v0.0.0-20200725001727-48d03e197117/go.mod h1:Qh+VXOB6hj60VmlgsmY+R1w+dFuHK246UueM4SAqZG0= -github.com/libopenstorage/secrets v0.0.0-20231011182615-5f4b25ceede1 h1:bPR1KJK9pbSYuDPQzx5zXOT7Exj+y/K/8lpGU2KfzRc= -github.com/libopenstorage/secrets v0.0.0-20231011182615-5f4b25ceede1/go.mod h1:TB8PxROcwcNeaawFm45+XAj0lnZL2wRI3wTr/tZ3/bM= +github.com/libopenstorage/secrets v0.0.0-20240416031220-a17cf7f72c6c h1:sCgvz+9ukGwz0k9kHNzGm1zJLTOo5HT1F//9mtXZ08g= +github.com/libopenstorage/secrets v0.0.0-20240416031220-a17cf7f72c6c/go.mod h1:TB8PxROcwcNeaawFm45+XAj0lnZL2wRI3wTr/tZ3/bM= github.com/libopenstorage/stork v1.3.0-beta1.0.20200630005842-9255e7a98775/go.mod h1:qBSzYTJVHlOMg5RINNiHD1kBzlasnrc2uKLPZLgu1Qs= github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= @@ -2058,11 +2080,13 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+ github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= @@ -2113,8 +2137,8 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/openshift/api v0.0.0-20210105115604-44119421ec6b/go.mod h1:aqU5Cq+kqKKPbDMqxo9FojgDeSpNJI7iuskjXjtojDg= -github.com/openshift/api v0.0.0-20240115183315-0793e918179d h1:gtwDqGPf5QmsV8jvOUoDNbtyeby9QeLdsybNQ8mGqHQ= -github.com/openshift/api v0.0.0-20240115183315-0793e918179d/go.mod h1:CxgbWAlvu2iQB0UmKTtRu1YfepRg1/vJ64n2DlIEVz4= +github.com/openshift/api v0.0.0-20240301093301-ce10821dc999 h1:+S998xHiJApsJZjRAO8wyedU9GfqFd8mtwWly6LqHDo= +github.com/openshift/api v0.0.0-20240301093301-ce10821dc999/go.mod h1:CxgbWAlvu2iQB0UmKTtRu1YfepRg1/vJ64n2DlIEVz4= github.com/openshift/build-machinery-go v0.0.0-20200917070002-f171684f77ab/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= github.com/openshift/client-go v0.0.0-20210112165513-ebc401615f47/go.mod h1:u7NRAjtYVAKokiI9LouzTv4mhds8P4S1TwdVAfbjKSk= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -2221,6 +2245,12 @@ github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/f github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rook/kubectl-rook-ceph v0.9.2 h1:GjtAtv3xXsCGPuXF3LB8I+/pdkJk5OSXesaQjAjblRg= +github.com/rook/kubectl-rook-ceph v0.9.2/go.mod h1:QKt6eEPV+Q1DgSnI+xiUl0KjUXvFCN9yi9UWWiA+GCA= +github.com/rook/rook v1.15.4 h1:NLRs961bM6+U8IaAqJFSQ/IUdJAicy4PImF2dIA+yO4= +github.com/rook/rook v1.15.4/go.mod h1:/SklxXAcmvgkj5w+zZFXb5iImadQOTKduwtXVDhw/MY= +github.com/rook/rook/pkg/apis v0.0.0-20231204200402-5287527732f7 h1:jXRUM2OJDz6hwpO4fElAgUqdTKosO3LHV3fwEB6iYJM= +github.com/rook/rook/pkg/apis v0.0.0-20231204200402-5287527732f7/go.mod h1:ZnB1JWtsxJLz2Q3ylHFS4lE/2A1lw2zIOKN0uAmhiZM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= @@ -2289,6 +2319,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1 github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= +github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= +github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= @@ -2413,8 +2445,9 @@ 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.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-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-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -3130,7 +3163,6 @@ google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220208230804-65c12eb4c068/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= @@ -3425,6 +3457,7 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYs gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -3478,6 +3511,7 @@ 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.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.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= @@ -3486,8 +3520,9 @@ k8s.io/kms v0.31.1 h1:cGLyV3cIwb0ovpP/jtyIe2mEuQ/MkbhmeBF2IYCA9Io= k8s.io/kms v0.31.1/go.mod h1:OZKwl1fan3n3N5FFxnW5C4V3ygrah/3YXeJWS3O6+94= k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/kube-openapi v0.0.0-20240620174524-b456828f718b h1:Q9xmGWBvOGd8UJyccgpYlLosk/JlfP3xQLNkQlHJeXw= +k8s.io/kube-openapi v0.0.0-20240620174524-b456828f718b/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc= k8s.io/kubectl v0.31.1 h1:ih4JQJHxsEggFqDJEHSOdJ69ZxZftgeZvYo7M/cpp24= k8s.io/kubectl v0.31.1/go.mod h1:aNuQoR43W6MLAtXQ/Bu4GDmoHlbhHKuyD49lmTC8eJM= k8s.io/kubelet v0.31.1 h1:aAxwVxGzbbMKKk/FnSjvkN52K3LdHhjhzmYcyGBuE0c= diff --git a/vendor/github.com/Masterminds/semver/v3/.gitignore b/vendor/github.com/Masterminds/semver/v3/.gitignore new file mode 100644 index 00000000000..c5fb8c48c1d --- /dev/null +++ b/vendor/github.com/Masterminds/semver/v3/.gitignore @@ -0,0 +1 @@ +_fuzz/ diff --git a/vendor/github.com/Masterminds/semver/v3/.golangci.yml b/vendor/github.com/Masterminds/semver/v3/.golangci.yml new file mode 100644 index 00000000000..fbc6332592f --- /dev/null +++ b/vendor/github.com/Masterminds/semver/v3/.golangci.yml @@ -0,0 +1,27 @@ +run: + deadline: 2m + +linters: + disable-all: true + enable: + - misspell + - govet + - staticcheck + - errcheck + - unparam + - ineffassign + - nakedret + - gocyclo + - dupl + - goimports + - revive + - gosec + - gosimple + - typecheck + - unused + +linters-settings: + gofmt: + simplify: true + dupl: + threshold: 600 diff --git a/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md b/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md new file mode 100644 index 00000000000..bfdcdfb43ca --- /dev/null +++ b/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md @@ -0,0 +1,214 @@ +# Changelog + +## 3.2.0 (2022-11-28) + +### Added + +- #190: Added text marshaling and unmarshaling +- #167: Added JSON marshalling for constraints (thanks @SimonTheLeg) +- #173: Implement encoding.TextMarshaler and encoding.TextUnmarshaler on Version (thanks @MarkRosemaker) +- #179: Added New() version constructor (thanks @kazhuravlev) + +### Changed + +- #182/#183: Updated CI testing setup + +### Fixed + +- #186: Fixing issue where validation of constraint section gave false positives +- #176: Fix constraints check with *-0 (thanks @mtt0) +- #181: Fixed Caret operator (^) gives unexpected results when the minor version in constraint is 0 (thanks @arshchimni) +- #161: Fixed godoc (thanks @afirth) + +## 3.1.1 (2020-11-23) + +### Fixed + +- #158: Fixed issue with generated regex operation order that could cause problem + +## 3.1.0 (2020-04-15) + +### Added + +- #131: Add support for serializing/deserializing SQL (thanks @ryancurrah) + +### Changed + +- #148: More accurate validation messages on constraints + +## 3.0.3 (2019-12-13) + +### Fixed + +- #141: Fixed issue with <= comparison + +## 3.0.2 (2019-11-14) + +### Fixed + +- #134: Fixed broken constraint checking with ^0.0 (thanks @krmichelos) + +## 3.0.1 (2019-09-13) + +### Fixed + +- #125: Fixes issue with module path for v3 + +## 3.0.0 (2019-09-12) + +This is a major release of the semver package which includes API changes. The Go +API is compatible with ^1. The Go API was not changed because many people are using +`go get` without Go modules for their applications and API breaking changes cause +errors which we have or would need to support. + +The changes in this release are the handling based on the data passed into the +functions. These are described in the added and changed sections below. + +### Added + +- StrictNewVersion function. This is similar to NewVersion but will return an + error if the version passed in is not a strict semantic version. For example, + 1.2.3 would pass but v1.2.3 or 1.2 would fail because they are not strictly + speaking semantic versions. This function is faster, performs fewer operations, + and uses fewer allocations than NewVersion. +- Fuzzing has been performed on NewVersion, StrictNewVersion, and NewConstraint. + The Makefile contains the operations used. For more information on you can start + on Wikipedia at https://en.wikipedia.org/wiki/Fuzzing +- Now using Go modules + +### Changed + +- NewVersion has proper prerelease and metadata validation with error messages + to signal an issue with either of them +- ^ now operates using a similar set of rules to npm/js and Rust/Cargo. If the + version is >=1 the ^ ranges works the same as v1. For major versions of 0 the + rules have changed. The minor version is treated as the stable version unless + a patch is specified and then it is equivalent to =. One difference from npm/js + is that prereleases there are only to a specific version (e.g. 1.2.3). + Prereleases here look over multiple versions and follow semantic version + ordering rules. This pattern now follows along with the expected and requested + handling of this packaged by numerous users. + +## 1.5.0 (2019-09-11) + +### Added + +- #103: Add basic fuzzing for `NewVersion()` (thanks @jesse-c) + +### Changed + +- #82: Clarify wildcard meaning in range constraints and update tests for it (thanks @greysteil) +- #83: Clarify caret operator range for pre-1.0.0 dependencies (thanks @greysteil) +- #72: Adding docs comment pointing to vert for a cli +- #71: Update the docs on pre-release comparator handling +- #89: Test with new go versions (thanks @thedevsaddam) +- #87: Added $ to ValidPrerelease for better validation (thanks @jeremycarroll) + +### Fixed + +- #78: Fix unchecked error in example code (thanks @ravron) +- #70: Fix the handling of pre-releases and the 0.0.0 release edge case +- #97: Fixed copyright file for proper display on GitHub +- #107: Fix handling prerelease when sorting alphanum and num +- #109: Fixed where Validate sometimes returns wrong message on error + +## 1.4.2 (2018-04-10) + +### Changed + +- #72: Updated the docs to point to vert for a console appliaction +- #71: Update the docs on pre-release comparator handling + +### Fixed + +- #70: Fix the handling of pre-releases and the 0.0.0 release edge case + +## 1.4.1 (2018-04-02) + +### Fixed + +- Fixed #64: Fix pre-release precedence issue (thanks @uudashr) + +## 1.4.0 (2017-10-04) + +### Changed + +- #61: Update NewVersion to parse ints with a 64bit int size (thanks @zknill) + +## 1.3.1 (2017-07-10) + +### Fixed + +- Fixed #57: number comparisons in prerelease sometimes inaccurate + +## 1.3.0 (2017-05-02) + +### Added + +- #45: Added json (un)marshaling support (thanks @mh-cbon) +- Stability marker. See https://masterminds.github.io/stability/ + +### Fixed + +- #51: Fix handling of single digit tilde constraint (thanks @dgodd) + +### Changed + +- #55: The godoc icon moved from png to svg + +## 1.2.3 (2017-04-03) + +### Fixed + +- #46: Fixed 0.x.x and 0.0.x in constraints being treated as * + +## Release 1.2.2 (2016-12-13) + +### Fixed + +- #34: Fixed issue where hyphen range was not working with pre-release parsing. + +## Release 1.2.1 (2016-11-28) + +### Fixed + +- #24: Fixed edge case issue where constraint "> 0" does not handle "0.0.1-alpha" + properly. + +## Release 1.2.0 (2016-11-04) + +### Added + +- #20: Added MustParse function for versions (thanks @adamreese) +- #15: Added increment methods on versions (thanks @mh-cbon) + +### Fixed + +- Issue #21: Per the SemVer spec (section 9) a pre-release is unstable and + might not satisfy the intended compatibility. The change here ignores pre-releases + on constraint checks (e.g., ~ or ^) when a pre-release is not part of the + constraint. For example, `^1.2.3` will ignore pre-releases while + `^1.2.3-alpha` will include them. + +## Release 1.1.1 (2016-06-30) + +### Changed + +- Issue #9: Speed up version comparison performance (thanks @sdboyer) +- Issue #8: Added benchmarks (thanks @sdboyer) +- Updated Go Report Card URL to new location +- Updated Readme to add code snippet formatting (thanks @mh-cbon) +- Updating tagging to v[SemVer] structure for compatibility with other tools. + +## Release 1.1.0 (2016-03-11) + +- Issue #2: Implemented validation to provide reasons a versions failed a + constraint. + +## Release 1.0.1 (2015-12-31) + +- Fixed #1: * constraint failing on valid versions. + +## Release 1.0.0 (2015-10-20) + +- Initial release diff --git a/vendor/github.com/Masterminds/semver/v3/LICENSE.txt b/vendor/github.com/Masterminds/semver/v3/LICENSE.txt new file mode 100644 index 00000000000..9ff7da9c48b --- /dev/null +++ b/vendor/github.com/Masterminds/semver/v3/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (C) 2014-2019, Matt Butcher and Matt Farina + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/Masterminds/semver/v3/Makefile b/vendor/github.com/Masterminds/semver/v3/Makefile new file mode 100644 index 00000000000..0e7b5c7138e --- /dev/null +++ b/vendor/github.com/Masterminds/semver/v3/Makefile @@ -0,0 +1,30 @@ +GOPATH=$(shell go env GOPATH) +GOLANGCI_LINT=$(GOPATH)/bin/golangci-lint + +.PHONY: lint +lint: $(GOLANGCI_LINT) + @echo "==> Linting codebase" + @$(GOLANGCI_LINT) run + +.PHONY: test +test: + @echo "==> Running tests" + GO111MODULE=on go test -v + +.PHONY: test-cover +test-cover: + @echo "==> Running Tests with coverage" + GO111MODULE=on go test -cover . + +.PHONY: fuzz +fuzz: + @echo "==> Running Fuzz Tests" + go test -fuzz=FuzzNewVersion -fuzztime=15s . + go test -fuzz=FuzzStrictNewVersion -fuzztime=15s . + go test -fuzz=FuzzNewConstraint -fuzztime=15s . + +$(GOLANGCI_LINT): + # Install golangci-lint. The configuration for it is in the .golangci.yml + # file in the root of the repository + echo ${GOPATH} + curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.17.1 diff --git a/vendor/github.com/Masterminds/semver/v3/README.md b/vendor/github.com/Masterminds/semver/v3/README.md new file mode 100644 index 00000000000..eab8cac3b7f --- /dev/null +++ b/vendor/github.com/Masterminds/semver/v3/README.md @@ -0,0 +1,258 @@ +# SemVer + +The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to: + +* Parse semantic versions +* Sort semantic versions +* Check if a semantic version fits within a set of constraints +* Optionally work with a `v` prefix + +[![Stability: +Active](https://masterminds.github.io/stability/active.svg)](https://masterminds.github.io/stability/active.html) +[![](https://github.com/Masterminds/semver/workflows/Tests/badge.svg)](https://github.com/Masterminds/semver/actions) +[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/Masterminds/semver/v3) +[![Go Report Card](https://goreportcard.com/badge/github.com/Masterminds/semver)](https://goreportcard.com/report/github.com/Masterminds/semver) + +If you are looking for a command line tool for version comparisons please see +[vert](https://github.com/Masterminds/vert) which uses this library. + +## Package Versions + +Note, import `github.com/github.com/Masterminds/semver/v3` to use the latest version. + +There are three major versions fo the `semver` package. + +* 3.x.x is the stable and active version. This version is focused on constraint + compatibility for range handling in other tools from other languages. It has + a similar API to the v1 releases. The development of this version is on the master + branch. The documentation for this version is below. +* 2.x was developed primarily for [dep](https://github.com/golang/dep). There are + no tagged releases and the development was performed by [@sdboyer](https://github.com/sdboyer). + There are API breaking changes from v1. This version lives on the [2.x branch](https://github.com/Masterminds/semver/tree/2.x). +* 1.x.x is the original release. It is no longer maintained. You should use the + v3 release instead. You can read the documentation for the 1.x.x release + [here](https://github.com/Masterminds/semver/blob/release-1/README.md). + +## Parsing Semantic Versions + +There are two functions that can parse semantic versions. The `StrictNewVersion` +function only parses valid version 2 semantic versions as outlined in the +specification. The `NewVersion` function attempts to coerce a version into a +semantic version and parse it. For example, if there is a leading v or a version +listed without all 3 parts (e.g. `v1.2`) it will attempt to coerce it into a valid +semantic version (e.g., 1.2.0). In both cases a `Version` object is returned +that can be sorted, compared, and used in constraints. + +When parsing a version an error is returned if there is an issue parsing the +version. For example, + + v, err := semver.NewVersion("1.2.3-beta.1+build345") + +The version object has methods to get the parts of the version, compare it to +other versions, convert the version back into a string, and get the original +string. Getting the original string is useful if the semantic version was coerced +into a valid form. + +## Sorting Semantic Versions + +A set of versions can be sorted using the `sort` package from the standard library. +For example, + +```go +raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} +vs := make([]*semver.Version, len(raw)) +for i, r := range raw { + v, err := semver.NewVersion(r) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + vs[i] = v +} + +sort.Sort(semver.Collection(vs)) +``` + +## Checking Version Constraints + +There are two methods for comparing versions. One uses comparison methods on +`Version` instances and the other uses `Constraints`. There are some important +differences to notes between these two methods of comparison. + +1. When two versions are compared using functions such as `Compare`, `LessThan`, + and others it will follow the specification and always include prereleases + within the comparison. It will provide an answer that is valid with the + comparison section of the spec at https://semver.org/#spec-item-11 +2. When constraint checking is used for checks or validation it will follow a + different set of rules that are common for ranges with tools like npm/js + and Rust/Cargo. This includes considering prereleases to be invalid if the + ranges does not include one. If you want to have it include pre-releases a + simple solution is to include `-0` in your range. +3. Constraint ranges can have some complex rules including the shorthand use of + ~ and ^. For more details on those see the options below. + +There are differences between the two methods or checking versions because the +comparison methods on `Version` follow the specification while comparison ranges +are not part of the specification. Different packages and tools have taken it +upon themselves to come up with range rules. This has resulted in differences. +For example, npm/js and Cargo/Rust follow similar patterns while PHP has a +different pattern for ^. The comparison features in this package follow the +npm/js and Cargo/Rust lead because applications using it have followed similar +patters with their versions. + +Checking a version against version constraints is one of the most featureful +parts of the package. + +```go +c, err := semver.NewConstraint(">= 1.2.3") +if err != nil { + // Handle constraint not being parsable. +} + +v, err := semver.NewVersion("1.3") +if err != nil { + // Handle version not being parsable. +} +// Check if the version meets the constraints. The a variable will be true. +a := c.Check(v) +``` + +### Basic Comparisons + +There are two elements to the comparisons. First, a comparison string is a list +of space or comma separated AND comparisons. These are then separated by || (OR) +comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a +comparison that's greater than or equal to 1.2 and less than 3.0.0 or is +greater than or equal to 4.2.3. + +The basic comparisons are: + +* `=`: equal (aliased to no operator) +* `!=`: not equal +* `>`: greater than +* `<`: less than +* `>=`: greater than or equal to +* `<=`: less than or equal to + +### Working With Prerelease Versions + +Pre-releases, for those not familiar with them, are used for software releases +prior to stable or generally available releases. Examples of prereleases include +development, alpha, beta, and release candidate releases. A prerelease may be +a version such as `1.2.3-beta.1` while the stable release would be `1.2.3`. In the +order of precedence, prereleases come before their associated releases. In this +example `1.2.3-beta.1 < 1.2.3`. + +According to the Semantic Version specification prereleases may not be +API compliant with their release counterpart. It says, + +> A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. + +SemVer comparisons using constraints without a prerelease comparator will skip +prerelease versions. For example, `>=1.2.3` will skip prereleases when looking +at a list of releases while `>=1.2.3-0` will evaluate and find prereleases. + +The reason for the `0` as a pre-release version in the example comparison is +because pre-releases can only contain ASCII alphanumerics and hyphens (along with +`.` separators), per the spec. Sorting happens in ASCII sort order, again per the +spec. The lowest character is a `0` in ASCII sort order +(see an [ASCII Table](http://www.asciitable.com/)) + +Understanding ASCII sort ordering is important because A-Z comes before a-z. That +means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case +sensitivity doesn't apply here. This is due to ASCII sort ordering which is what +the spec specifies. + +### Hyphen Range Comparisons + +There are multiple methods to handle ranges and the first is hyphens ranges. +These look like: + +* `1.2 - 1.4.5` which is equivalent to `>= 1.2 <= 1.4.5` +* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` + +### Wildcards In Comparisons + +The `x`, `X`, and `*` characters can be used as a wildcard character. This works +for all comparison operators. When used on the `=` operator it falls +back to the patch level comparison (see tilde below). For example, + +* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` +* `>= 1.2.x` is equivalent to `>= 1.2.0` +* `<= 2.x` is equivalent to `< 3` +* `*` is equivalent to `>= 0.0.0` + +### Tilde Range Comparisons (Patch) + +The tilde (`~`) comparison operator is for patch level ranges when a minor +version is specified and major level changes when the minor number is missing. +For example, + +* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0` +* `~1` is equivalent to `>= 1, < 2` +* `~2.3` is equivalent to `>= 2.3, < 2.4` +* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` +* `~1.x` is equivalent to `>= 1, < 2` + +### Caret Range Comparisons (Major) + +The caret (`^`) comparison operator is for major level changes once a stable +(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts +as the API stability level. This is useful when comparisons of API versions as a +major change is API breaking. For example, + +* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` +* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` +* `^2.3` is equivalent to `>= 2.3, < 3` +* `^2.x` is equivalent to `>= 2.0.0, < 3` +* `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` +* `^0.2` is equivalent to `>=0.2.0 <0.3.0` +* `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` +* `^0.0` is equivalent to `>=0.0.0 <0.1.0` +* `^0` is equivalent to `>=0.0.0 <1.0.0` + +## Validation + +In addition to testing a version against a constraint, a version can be validated +against a constraint. When validation fails a slice of errors containing why a +version didn't meet the constraint is returned. For example, + +```go +c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") +if err != nil { + // Handle constraint not being parseable. +} + +v, err := semver.NewVersion("1.3") +if err != nil { + // Handle version not being parseable. +} + +// Validate a version against a constraint. +a, msgs := c.Validate(v) +// a is false +for _, m := range msgs { + fmt.Println(m) + + // Loops over the errors which would read + // "1.3 is greater than 1.2.3" + // "1.3 is less than 1.4" +} +``` + +## Contribute + +If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues) +or [create a pull request](https://github.com/Masterminds/semver/pulls). + +## Security + +Security is an important consideration for this project. The project currently +uses the following tools to help discover security issues: + +* [CodeQL](https://github.com/Masterminds/semver) +* [gosec](https://github.com/securego/gosec) +* Daily Fuzz testing + +If you believe you have found a security vulnerability you can privately disclose +it through the [GitHub security page](https://github.com/Masterminds/semver/security). diff --git a/vendor/github.com/Masterminds/semver/v3/SECURITY.md b/vendor/github.com/Masterminds/semver/v3/SECURITY.md new file mode 100644 index 00000000000..a30a66b1f74 --- /dev/null +++ b/vendor/github.com/Masterminds/semver/v3/SECURITY.md @@ -0,0 +1,19 @@ +# Security Policy + +## Supported Versions + +The following versions of semver are currently supported: + +| Version | Supported | +| ------- | ------------------ | +| 3.x | :white_check_mark: | +| 2.x | :x: | +| 1.x | :x: | + +Fixes are only released for the latest minor version in the form of a patch release. + +## Reporting a Vulnerability + +You can privately disclose a vulnerability through GitHubs +[private vulnerability reporting](https://github.com/Masterminds/semver/security/advisories) +mechanism. diff --git a/vendor/github.com/Masterminds/semver/v3/collection.go b/vendor/github.com/Masterminds/semver/v3/collection.go new file mode 100644 index 00000000000..a78235895fd --- /dev/null +++ b/vendor/github.com/Masterminds/semver/v3/collection.go @@ -0,0 +1,24 @@ +package semver + +// Collection is a collection of Version instances and implements the sort +// interface. See the sort package for more details. +// https://golang.org/pkg/sort/ +type Collection []*Version + +// Len returns the length of a collection. The number of Version instances +// on the slice. +func (c Collection) Len() int { + return len(c) +} + +// Less is needed for the sort interface to compare two Version objects on the +// slice. If checks if one is less than the other. +func (c Collection) Less(i, j int) bool { + return c[i].LessThan(c[j]) +} + +// Swap is needed for the sort interface to replace the Version objects +// at two different positions in the slice. +func (c Collection) Swap(i, j int) { + c[i], c[j] = c[j], c[i] +} diff --git a/vendor/github.com/Masterminds/semver/v3/constraints.go b/vendor/github.com/Masterminds/semver/v3/constraints.go new file mode 100644 index 00000000000..8461c7ed903 --- /dev/null +++ b/vendor/github.com/Masterminds/semver/v3/constraints.go @@ -0,0 +1,594 @@ +package semver + +import ( + "bytes" + "errors" + "fmt" + "regexp" + "strings" +) + +// Constraints is one or more constraint that a semantic version can be +// checked against. +type Constraints struct { + constraints [][]*constraint +} + +// NewConstraint returns a Constraints instance that a Version instance can +// be checked against. If there is a parse error it will be returned. +func NewConstraint(c string) (*Constraints, error) { + + // Rewrite - ranges into a comparison operation. + c = rewriteRange(c) + + ors := strings.Split(c, "||") + or := make([][]*constraint, len(ors)) + for k, v := range ors { + + // TODO: Find a way to validate and fetch all the constraints in a simpler form + + // Validate the segment + if !validConstraintRegex.MatchString(v) { + return nil, fmt.Errorf("improper constraint: %s", v) + } + + cs := findConstraintRegex.FindAllString(v, -1) + if cs == nil { + cs = append(cs, v) + } + result := make([]*constraint, len(cs)) + for i, s := range cs { + pc, err := parseConstraint(s) + if err != nil { + return nil, err + } + + result[i] = pc + } + or[k] = result + } + + o := &Constraints{constraints: or} + return o, nil +} + +// Check tests if a version satisfies the constraints. +func (cs Constraints) Check(v *Version) bool { + // TODO(mattfarina): For v4 of this library consolidate the Check and Validate + // functions as the underlying functions make that possible now. + // loop over the ORs and check the inner ANDs + for _, o := range cs.constraints { + joy := true + for _, c := range o { + if check, _ := c.check(v); !check { + joy = false + break + } + } + + if joy { + return true + } + } + + return false +} + +// Validate checks if a version satisfies a constraint. If not a slice of +// reasons for the failure are returned in addition to a bool. +func (cs Constraints) Validate(v *Version) (bool, []error) { + // loop over the ORs and check the inner ANDs + var e []error + + // Capture the prerelease message only once. When it happens the first time + // this var is marked + var prerelesase bool + for _, o := range cs.constraints { + joy := true + for _, c := range o { + // Before running the check handle the case there the version is + // a prerelease and the check is not searching for prereleases. + if c.con.pre == "" && v.pre != "" { + if !prerelesase { + em := fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + e = append(e, em) + prerelesase = true + } + joy = false + + } else { + + if _, err := c.check(v); err != nil { + e = append(e, err) + joy = false + } + } + } + + if joy { + return true, []error{} + } + } + + return false, e +} + +func (cs Constraints) String() string { + buf := make([]string, len(cs.constraints)) + var tmp bytes.Buffer + + for k, v := range cs.constraints { + tmp.Reset() + vlen := len(v) + for kk, c := range v { + tmp.WriteString(c.string()) + + // Space separate the AND conditions + if vlen > 1 && kk < vlen-1 { + tmp.WriteString(" ") + } + } + buf[k] = tmp.String() + } + + return strings.Join(buf, " || ") +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (cs *Constraints) UnmarshalText(text []byte) error { + temp, err := NewConstraint(string(text)) + if err != nil { + return err + } + + *cs = *temp + + return nil +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (cs Constraints) MarshalText() ([]byte, error) { + return []byte(cs.String()), nil +} + +var constraintOps map[string]cfunc +var constraintRegex *regexp.Regexp +var constraintRangeRegex *regexp.Regexp + +// Used to find individual constraints within a multi-constraint string +var findConstraintRegex *regexp.Regexp + +// Used to validate an segment of ANDs is valid +var validConstraintRegex *regexp.Regexp + +const cvRegex string = `v?([0-9|x|X|\*]+)(\.[0-9|x|X|\*]+)?(\.[0-9|x|X|\*]+)?` + + `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + + `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + +func init() { + constraintOps = map[string]cfunc{ + "": constraintTildeOrEqual, + "=": constraintTildeOrEqual, + "!=": constraintNotEqual, + ">": constraintGreaterThan, + "<": constraintLessThan, + ">=": constraintGreaterThanEqual, + "=>": constraintGreaterThanEqual, + "<=": constraintLessThanEqual, + "=<": constraintLessThanEqual, + "~": constraintTilde, + "~>": constraintTilde, + "^": constraintCaret, + } + + ops := `=||!=|>|<|>=|=>|<=|=<|~|~>|\^` + + constraintRegex = regexp.MustCompile(fmt.Sprintf( + `^\s*(%s)\s*(%s)\s*$`, + ops, + cvRegex)) + + constraintRangeRegex = regexp.MustCompile(fmt.Sprintf( + `\s*(%s)\s+-\s+(%s)\s*`, + cvRegex, cvRegex)) + + findConstraintRegex = regexp.MustCompile(fmt.Sprintf( + `(%s)\s*(%s)`, + ops, + cvRegex)) + + // The first time a constraint shows up will look slightly different from + // future times it shows up due to a leading space or comma in a given + // string. + validConstraintRegex = regexp.MustCompile(fmt.Sprintf( + `^(\s*(%s)\s*(%s)\s*)((?:\s+|,\s*)(%s)\s*(%s)\s*)*$`, + ops, + cvRegex, + ops, + cvRegex)) +} + +// An individual constraint +type constraint struct { + // The version used in the constraint check. For example, if a constraint + // is '<= 2.0.0' the con a version instance representing 2.0.0. + con *Version + + // The original parsed version (e.g., 4.x from != 4.x) + orig string + + // The original operator for the constraint + origfunc string + + // When an x is used as part of the version (e.g., 1.x) + minorDirty bool + dirty bool + patchDirty bool +} + +// Check if a version meets the constraint +func (c *constraint) check(v *Version) (bool, error) { + return constraintOps[c.origfunc](v, c) +} + +// String prints an individual constraint into a string +func (c *constraint) string() string { + return c.origfunc + c.orig +} + +type cfunc func(v *Version, c *constraint) (bool, error) + +func parseConstraint(c string) (*constraint, error) { + if len(c) > 0 { + m := constraintRegex.FindStringSubmatch(c) + if m == nil { + return nil, fmt.Errorf("improper constraint: %s", c) + } + + cs := &constraint{ + orig: m[2], + origfunc: m[1], + } + + ver := m[2] + minorDirty := false + patchDirty := false + dirty := false + if isX(m[3]) || m[3] == "" { + ver = fmt.Sprintf("0.0.0%s", m[6]) + dirty = true + } else if isX(strings.TrimPrefix(m[4], ".")) || m[4] == "" { + minorDirty = true + dirty = true + ver = fmt.Sprintf("%s.0.0%s", m[3], m[6]) + } else if isX(strings.TrimPrefix(m[5], ".")) || m[5] == "" { + dirty = true + patchDirty = true + ver = fmt.Sprintf("%s%s.0%s", m[3], m[4], m[6]) + } + + con, err := NewVersion(ver) + if err != nil { + + // The constraintRegex should catch any regex parsing errors. So, + // we should never get here. + return nil, errors.New("constraint Parser Error") + } + + cs.con = con + cs.minorDirty = minorDirty + cs.patchDirty = patchDirty + cs.dirty = dirty + + return cs, nil + } + + // The rest is the special case where an empty string was passed in which + // is equivalent to * or >=0.0.0 + con, err := StrictNewVersion("0.0.0") + if err != nil { + + // The constraintRegex should catch any regex parsing errors. So, + // we should never get here. + return nil, errors.New("constraint Parser Error") + } + + cs := &constraint{ + con: con, + orig: c, + origfunc: "", + minorDirty: false, + patchDirty: false, + dirty: true, + } + return cs, nil +} + +// Constraint functions +func constraintNotEqual(v *Version, c *constraint) (bool, error) { + if c.dirty { + + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + if c.con.Major() != v.Major() { + return true, nil + } + if c.con.Minor() != v.Minor() && !c.minorDirty { + return true, nil + } else if c.minorDirty { + return false, fmt.Errorf("%s is equal to %s", v, c.orig) + } else if c.con.Patch() != v.Patch() && !c.patchDirty { + return true, nil + } else if c.patchDirty { + // Need to handle prereleases if present + if v.Prerelease() != "" || c.con.Prerelease() != "" { + eq := comparePrerelease(v.Prerelease(), c.con.Prerelease()) != 0 + if eq { + return true, nil + } + return false, fmt.Errorf("%s is equal to %s", v, c.orig) + } + return false, fmt.Errorf("%s is equal to %s", v, c.orig) + } + } + + eq := v.Equal(c.con) + if eq { + return false, fmt.Errorf("%s is equal to %s", v, c.orig) + } + + return true, nil +} + +func constraintGreaterThan(v *Version, c *constraint) (bool, error) { + + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + var eq bool + + if !c.dirty { + eq = v.Compare(c.con) == 1 + if eq { + return true, nil + } + return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) + } + + if v.Major() > c.con.Major() { + return true, nil + } else if v.Major() < c.con.Major() { + return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) + } else if c.minorDirty { + // This is a range case such as >11. When the version is something like + // 11.1.0 is it not > 11. For that we would need 12 or higher + return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) + } else if c.patchDirty { + // This is for ranges such as >11.1. A version of 11.1.1 is not greater + // which one of 11.2.1 is greater + eq = v.Minor() > c.con.Minor() + if eq { + return true, nil + } + return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) + } + + // If we have gotten here we are not comparing pre-preleases and can use the + // Compare function to accomplish that. + eq = v.Compare(c.con) == 1 + if eq { + return true, nil + } + return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) +} + +func constraintLessThan(v *Version, c *constraint) (bool, error) { + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + eq := v.Compare(c.con) < 0 + if eq { + return true, nil + } + return false, fmt.Errorf("%s is greater than or equal to %s", v, c.orig) +} + +func constraintGreaterThanEqual(v *Version, c *constraint) (bool, error) { + + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + eq := v.Compare(c.con) >= 0 + if eq { + return true, nil + } + return false, fmt.Errorf("%s is less than %s", v, c.orig) +} + +func constraintLessThanEqual(v *Version, c *constraint) (bool, error) { + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + var eq bool + + if !c.dirty { + eq = v.Compare(c.con) <= 0 + if eq { + return true, nil + } + return false, fmt.Errorf("%s is greater than %s", v, c.orig) + } + + if v.Major() > c.con.Major() { + return false, fmt.Errorf("%s is greater than %s", v, c.orig) + } else if v.Major() == c.con.Major() && v.Minor() > c.con.Minor() && !c.minorDirty { + return false, fmt.Errorf("%s is greater than %s", v, c.orig) + } + + return true, nil +} + +// ~*, ~>* --> >= 0.0.0 (any) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0, <3.0.0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0, <2.1.0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0 +func constraintTilde(v *Version, c *constraint) (bool, error) { + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + if v.LessThan(c.con) { + return false, fmt.Errorf("%s is less than %s", v, c.orig) + } + + // ~0.0.0 is a special case where all constraints are accepted. It's + // equivalent to >= 0.0.0. + if c.con.Major() == 0 && c.con.Minor() == 0 && c.con.Patch() == 0 && + !c.minorDirty && !c.patchDirty { + return true, nil + } + + if v.Major() != c.con.Major() { + return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig) + } + + if v.Minor() != c.con.Minor() && !c.minorDirty { + return false, fmt.Errorf("%s does not have same major and minor version as %s", v, c.orig) + } + + return true, nil +} + +// When there is a .x (dirty) status it automatically opts in to ~. Otherwise +// it's a straight = +func constraintTildeOrEqual(v *Version, c *constraint) (bool, error) { + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + if c.dirty { + return constraintTilde(v, c) + } + + eq := v.Equal(c.con) + if eq { + return true, nil + } + + return false, fmt.Errorf("%s is not equal to %s", v, c.orig) +} + +// ^* --> (any) +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2 --> >=1.2.0 <2.0.0 +// ^1 --> >=1.0.0 <2.0.0 +// ^0.2.3 --> >=0.2.3 <0.3.0 +// ^0.2 --> >=0.2.0 <0.3.0 +// ^0.0.3 --> >=0.0.3 <0.0.4 +// ^0.0 --> >=0.0.0 <0.1.0 +// ^0 --> >=0.0.0 <1.0.0 +func constraintCaret(v *Version, c *constraint) (bool, error) { + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + // This less than handles prereleases + if v.LessThan(c.con) { + return false, fmt.Errorf("%s is less than %s", v, c.orig) + } + + var eq bool + + // ^ when the major > 0 is >=x.y.z < x+1 + if c.con.Major() > 0 || c.minorDirty { + + // ^ has to be within a major range for > 0. Everything less than was + // filtered out with the LessThan call above. This filters out those + // that greater but not within the same major range. + eq = v.Major() == c.con.Major() + if eq { + return true, nil + } + return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig) + } + + // ^ when the major is 0 and minor > 0 is >=0.y.z < 0.y+1 + if c.con.Major() == 0 && v.Major() > 0 { + return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig) + } + // If the con Minor is > 0 it is not dirty + if c.con.Minor() > 0 || c.patchDirty { + eq = v.Minor() == c.con.Minor() + if eq { + return true, nil + } + return false, fmt.Errorf("%s does not have same minor version as %s. Expected minor versions to match when constraint major version is 0", v, c.orig) + } + // ^ when the minor is 0 and minor > 0 is =0.0.z + if c.con.Minor() == 0 && v.Minor() > 0 { + return false, fmt.Errorf("%s does not have same minor version as %s", v, c.orig) + } + + // At this point the major is 0 and the minor is 0 and not dirty. The patch + // is not dirty so we need to check if they are equal. If they are not equal + eq = c.con.Patch() == v.Patch() + if eq { + return true, nil + } + return false, fmt.Errorf("%s does not equal %s. Expect version and constraint to equal when major and minor versions are 0", v, c.orig) +} + +func isX(x string) bool { + switch x { + case "x", "*", "X": + return true + default: + return false + } +} + +func rewriteRange(i string) string { + m := constraintRangeRegex.FindAllStringSubmatch(i, -1) + if m == nil { + return i + } + o := i + for _, v := range m { + t := fmt.Sprintf(">= %s, <= %s ", v[1], v[11]) + o = strings.Replace(o, v[0], t, 1) + } + + return o +} diff --git a/vendor/github.com/Masterminds/semver/v3/doc.go b/vendor/github.com/Masterminds/semver/v3/doc.go new file mode 100644 index 00000000000..74f97caa57f --- /dev/null +++ b/vendor/github.com/Masterminds/semver/v3/doc.go @@ -0,0 +1,184 @@ +/* +Package semver provides the ability to work with Semantic Versions (http://semver.org) in Go. + +Specifically it provides the ability to: + + - Parse semantic versions + - Sort semantic versions + - Check if a semantic version fits within a set of constraints + - Optionally work with a `v` prefix + +# Parsing Semantic Versions + +There are two functions that can parse semantic versions. The `StrictNewVersion` +function only parses valid version 2 semantic versions as outlined in the +specification. The `NewVersion` function attempts to coerce a version into a +semantic version and parse it. For example, if there is a leading v or a version +listed without all 3 parts (e.g. 1.2) it will attempt to coerce it into a valid +semantic version (e.g., 1.2.0). In both cases a `Version` object is returned +that can be sorted, compared, and used in constraints. + +When parsing a version an optional error can be returned if there is an issue +parsing the version. For example, + + v, err := semver.NewVersion("1.2.3-beta.1+b345") + +The version object has methods to get the parts of the version, compare it to +other versions, convert the version back into a string, and get the original +string. For more details please see the documentation +at https://godoc.org/github.com/Masterminds/semver. + +# Sorting Semantic Versions + +A set of versions can be sorted using the `sort` package from the standard library. +For example, + + raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} + vs := make([]*semver.Version, len(raw)) + for i, r := range raw { + v, err := semver.NewVersion(r) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + vs[i] = v + } + + sort.Sort(semver.Collection(vs)) + +# Checking Version Constraints and Comparing Versions + +There are two methods for comparing versions. One uses comparison methods on +`Version` instances and the other is using Constraints. There are some important +differences to notes between these two methods of comparison. + + 1. When two versions are compared using functions such as `Compare`, `LessThan`, + and others it will follow the specification and always include prereleases + within the comparison. It will provide an answer valid with the comparison + spec section at https://semver.org/#spec-item-11 + 2. When constraint checking is used for checks or validation it will follow a + different set of rules that are common for ranges with tools like npm/js + and Rust/Cargo. This includes considering prereleases to be invalid if the + ranges does not include on. If you want to have it include pre-releases a + simple solution is to include `-0` in your range. + 3. Constraint ranges can have some complex rules including the shorthard use of + ~ and ^. For more details on those see the options below. + +There are differences between the two methods or checking versions because the +comparison methods on `Version` follow the specification while comparison ranges +are not part of the specification. Different packages and tools have taken it +upon themselves to come up with range rules. This has resulted in differences. +For example, npm/js and Cargo/Rust follow similar patterns which PHP has a +different pattern for ^. The comparison features in this package follow the +npm/js and Cargo/Rust lead because applications using it have followed similar +patters with their versions. + +Checking a version against version constraints is one of the most featureful +parts of the package. + + c, err := semver.NewConstraint(">= 1.2.3") + if err != nil { + // Handle constraint not being parsable. + } + + v, err := semver.NewVersion("1.3") + if err != nil { + // Handle version not being parsable. + } + // Check if the version meets the constraints. The a variable will be true. + a := c.Check(v) + +# Basic Comparisons + +There are two elements to the comparisons. First, a comparison string is a list +of comma or space separated AND comparisons. These are then separated by || (OR) +comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a +comparison that's greater than or equal to 1.2 and less than 3.0.0 or is +greater than or equal to 4.2.3. This can also be written as +`">= 1.2, < 3.0.0 || >= 4.2.3"` + +The basic comparisons are: + + - `=`: equal (aliased to no operator) + - `!=`: not equal + - `>`: greater than + - `<`: less than + - `>=`: greater than or equal to + - `<=`: less than or equal to + +# Hyphen Range Comparisons + +There are multiple methods to handle ranges and the first is hyphens ranges. +These look like: + + - `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5` + - `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` + +# Wildcards In Comparisons + +The `x`, `X`, and `*` characters can be used as a wildcard character. This works +for all comparison operators. When used on the `=` operator it falls +back to the tilde operation. For example, + + - `1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` + - `>= 1.2.x` is equivalent to `>= 1.2.0` + - `<= 2.x` is equivalent to `<= 3` + - `*` is equivalent to `>= 0.0.0` + +Tilde Range Comparisons (Patch) + +The tilde (`~`) comparison operator is for patch level ranges when a minor +version is specified and major level changes when the minor number is missing. +For example, + + - `~1.2.3` is equivalent to `>= 1.2.3 < 1.3.0` + - `~1` is equivalent to `>= 1, < 2` + - `~2.3` is equivalent to `>= 2.3 < 2.4` + - `~1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` + - `~1.x` is equivalent to `>= 1 < 2` + +Caret Range Comparisons (Major) + +The caret (`^`) comparison operator is for major level changes once a stable +(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts +as the API stability level. This is useful when comparisons of API versions as a +major change is API breaking. For example, + + - `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` + - `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` + - `^2.3` is equivalent to `>= 2.3, < 3` + - `^2.x` is equivalent to `>= 2.0.0, < 3` + - `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` + - `^0.2` is equivalent to `>=0.2.0 <0.3.0` + - `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` + - `^0.0` is equivalent to `>=0.0.0 <0.1.0` + - `^0` is equivalent to `>=0.0.0 <1.0.0` + +# Validation + +In addition to testing a version against a constraint, a version can be validated +against a constraint. When validation fails a slice of errors containing why a +version didn't meet the constraint is returned. For example, + + c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") + if err != nil { + // Handle constraint not being parseable. + } + + v, _ := semver.NewVersion("1.3") + if err != nil { + // Handle version not being parseable. + } + + // Validate a version against a constraint. + a, msgs := c.Validate(v) + // a is false + for _, m := range msgs { + fmt.Println(m) + + // Loops over the errors which would read + // "1.3 is greater than 1.2.3" + // "1.3 is less than 1.4" + } +*/ +package semver diff --git a/vendor/github.com/Masterminds/semver/v3/version.go b/vendor/github.com/Masterminds/semver/v3/version.go new file mode 100644 index 00000000000..7c4bed33474 --- /dev/null +++ b/vendor/github.com/Masterminds/semver/v3/version.go @@ -0,0 +1,639 @@ +package semver + +import ( + "bytes" + "database/sql/driver" + "encoding/json" + "errors" + "fmt" + "regexp" + "strconv" + "strings" +) + +// The compiled version of the regex created at init() is cached here so it +// only needs to be created once. +var versionRegex *regexp.Regexp + +var ( + // ErrInvalidSemVer is returned a version is found to be invalid when + // being parsed. + ErrInvalidSemVer = errors.New("Invalid Semantic Version") + + // ErrEmptyString is returned when an empty string is passed in for parsing. + ErrEmptyString = errors.New("Version string empty") + + // ErrInvalidCharacters is returned when invalid characters are found as + // part of a version + ErrInvalidCharacters = errors.New("Invalid characters in version") + + // ErrSegmentStartsZero is returned when a version segment starts with 0. + // This is invalid in SemVer. + ErrSegmentStartsZero = errors.New("Version segment starts with 0") + + // ErrInvalidMetadata is returned when the metadata is an invalid format + ErrInvalidMetadata = errors.New("Invalid Metadata string") + + // ErrInvalidPrerelease is returned when the pre-release is an invalid format + ErrInvalidPrerelease = errors.New("Invalid Prerelease string") +) + +// semVerRegex is the regular expression used to parse a semantic version. +const semVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` + + `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + + `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + +// Version represents a single semantic version. +type Version struct { + major, minor, patch uint64 + pre string + metadata string + original string +} + +func init() { + versionRegex = regexp.MustCompile("^" + semVerRegex + "$") +} + +const ( + num string = "0123456789" + allowed string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" + num +) + +// StrictNewVersion parses a given version and returns an instance of Version or +// an error if unable to parse the version. Only parses valid semantic versions. +// Performs checking that can find errors within the version. +// If you want to coerce a version such as 1 or 1.2 and parse it as the 1.x +// releases of semver did, use the NewVersion() function. +func StrictNewVersion(v string) (*Version, error) { + // Parsing here does not use RegEx in order to increase performance and reduce + // allocations. + + if len(v) == 0 { + return nil, ErrEmptyString + } + + // Split the parts into [0]major, [1]minor, and [2]patch,prerelease,build + parts := strings.SplitN(v, ".", 3) + if len(parts) != 3 { + return nil, ErrInvalidSemVer + } + + sv := &Version{ + original: v, + } + + // check for prerelease or build metadata + var extra []string + if strings.ContainsAny(parts[2], "-+") { + // Start with the build metadata first as it needs to be on the right + extra = strings.SplitN(parts[2], "+", 2) + if len(extra) > 1 { + // build metadata found + sv.metadata = extra[1] + parts[2] = extra[0] + } + + extra = strings.SplitN(parts[2], "-", 2) + if len(extra) > 1 { + // prerelease found + sv.pre = extra[1] + parts[2] = extra[0] + } + } + + // Validate the number segments are valid. This includes only having positive + // numbers and no leading 0's. + for _, p := range parts { + if !containsOnly(p, num) { + return nil, ErrInvalidCharacters + } + + if len(p) > 1 && p[0] == '0' { + return nil, ErrSegmentStartsZero + } + } + + // Extract the major, minor, and patch elements onto the returned Version + var err error + sv.major, err = strconv.ParseUint(parts[0], 10, 64) + if err != nil { + return nil, err + } + + sv.minor, err = strconv.ParseUint(parts[1], 10, 64) + if err != nil { + return nil, err + } + + sv.patch, err = strconv.ParseUint(parts[2], 10, 64) + if err != nil { + return nil, err + } + + // No prerelease or build metadata found so returning now as a fastpath. + if sv.pre == "" && sv.metadata == "" { + return sv, nil + } + + if sv.pre != "" { + if err = validatePrerelease(sv.pre); err != nil { + return nil, err + } + } + + if sv.metadata != "" { + if err = validateMetadata(sv.metadata); err != nil { + return nil, err + } + } + + return sv, nil +} + +// NewVersion parses a given version and returns an instance of Version or +// an error if unable to parse the version. If the version is SemVer-ish it +// attempts to convert it to SemVer. If you want to validate it was a strict +// semantic version at parse time see StrictNewVersion(). +func NewVersion(v string) (*Version, error) { + m := versionRegex.FindStringSubmatch(v) + if m == nil { + return nil, ErrInvalidSemVer + } + + sv := &Version{ + metadata: m[8], + pre: m[5], + original: v, + } + + var err error + sv.major, err = strconv.ParseUint(m[1], 10, 64) + if err != nil { + return nil, fmt.Errorf("Error parsing version segment: %s", err) + } + + if m[2] != "" { + sv.minor, err = strconv.ParseUint(strings.TrimPrefix(m[2], "."), 10, 64) + if err != nil { + return nil, fmt.Errorf("Error parsing version segment: %s", err) + } + } else { + sv.minor = 0 + } + + if m[3] != "" { + sv.patch, err = strconv.ParseUint(strings.TrimPrefix(m[3], "."), 10, 64) + if err != nil { + return nil, fmt.Errorf("Error parsing version segment: %s", err) + } + } else { + sv.patch = 0 + } + + // Perform some basic due diligence on the extra parts to ensure they are + // valid. + + if sv.pre != "" { + if err = validatePrerelease(sv.pre); err != nil { + return nil, err + } + } + + if sv.metadata != "" { + if err = validateMetadata(sv.metadata); err != nil { + return nil, err + } + } + + return sv, nil +} + +// New creates a new instance of Version with each of the parts passed in as +// arguments instead of parsing a version string. +func New(major, minor, patch uint64, pre, metadata string) *Version { + v := Version{ + major: major, + minor: minor, + patch: patch, + pre: pre, + metadata: metadata, + original: "", + } + + v.original = v.String() + + return &v +} + +// MustParse parses a given version and panics on error. +func MustParse(v string) *Version { + sv, err := NewVersion(v) + if err != nil { + panic(err) + } + return sv +} + +// String converts a Version object to a string. +// Note, if the original version contained a leading v this version will not. +// See the Original() method to retrieve the original value. Semantic Versions +// don't contain a leading v per the spec. Instead it's optional on +// implementation. +func (v Version) String() string { + var buf bytes.Buffer + + fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch) + if v.pre != "" { + fmt.Fprintf(&buf, "-%s", v.pre) + } + if v.metadata != "" { + fmt.Fprintf(&buf, "+%s", v.metadata) + } + + return buf.String() +} + +// Original returns the original value passed in to be parsed. +func (v *Version) Original() string { + return v.original +} + +// Major returns the major version. +func (v Version) Major() uint64 { + return v.major +} + +// Minor returns the minor version. +func (v Version) Minor() uint64 { + return v.minor +} + +// Patch returns the patch version. +func (v Version) Patch() uint64 { + return v.patch +} + +// Prerelease returns the pre-release version. +func (v Version) Prerelease() string { + return v.pre +} + +// Metadata returns the metadata on the version. +func (v Version) Metadata() string { + return v.metadata +} + +// originalVPrefix returns the original 'v' prefix if any. +func (v Version) originalVPrefix() string { + // Note, only lowercase v is supported as a prefix by the parser. + if v.original != "" && v.original[:1] == "v" { + return v.original[:1] + } + return "" +} + +// IncPatch produces the next patch version. +// If the current version does not have prerelease/metadata information, +// it unsets metadata and prerelease values, increments patch number. +// If the current version has any of prerelease or metadata information, +// it unsets both values and keeps current patch value +func (v Version) IncPatch() Version { + vNext := v + // according to http://semver.org/#spec-item-9 + // Pre-release versions have a lower precedence than the associated normal version. + // according to http://semver.org/#spec-item-10 + // Build metadata SHOULD be ignored when determining version precedence. + if v.pre != "" { + vNext.metadata = "" + vNext.pre = "" + } else { + vNext.metadata = "" + vNext.pre = "" + vNext.patch = v.patch + 1 + } + vNext.original = v.originalVPrefix() + "" + vNext.String() + return vNext +} + +// IncMinor produces the next minor version. +// Sets patch to 0. +// Increments minor number. +// Unsets metadata. +// Unsets prerelease status. +func (v Version) IncMinor() Version { + vNext := v + vNext.metadata = "" + vNext.pre = "" + vNext.patch = 0 + vNext.minor = v.minor + 1 + vNext.original = v.originalVPrefix() + "" + vNext.String() + return vNext +} + +// IncMajor produces the next major version. +// Sets patch to 0. +// Sets minor to 0. +// Increments major number. +// Unsets metadata. +// Unsets prerelease status. +func (v Version) IncMajor() Version { + vNext := v + vNext.metadata = "" + vNext.pre = "" + vNext.patch = 0 + vNext.minor = 0 + vNext.major = v.major + 1 + vNext.original = v.originalVPrefix() + "" + vNext.String() + return vNext +} + +// SetPrerelease defines the prerelease value. +// Value must not include the required 'hyphen' prefix. +func (v Version) SetPrerelease(prerelease string) (Version, error) { + vNext := v + if len(prerelease) > 0 { + if err := validatePrerelease(prerelease); err != nil { + return vNext, err + } + } + vNext.pre = prerelease + vNext.original = v.originalVPrefix() + "" + vNext.String() + return vNext, nil +} + +// SetMetadata defines metadata value. +// Value must not include the required 'plus' prefix. +func (v Version) SetMetadata(metadata string) (Version, error) { + vNext := v + if len(metadata) > 0 { + if err := validateMetadata(metadata); err != nil { + return vNext, err + } + } + vNext.metadata = metadata + vNext.original = v.originalVPrefix() + "" + vNext.String() + return vNext, nil +} + +// LessThan tests if one version is less than another one. +func (v *Version) LessThan(o *Version) bool { + return v.Compare(o) < 0 +} + +// GreaterThan tests if one version is greater than another one. +func (v *Version) GreaterThan(o *Version) bool { + return v.Compare(o) > 0 +} + +// Equal tests if two versions are equal to each other. +// Note, versions can be equal with different metadata since metadata +// is not considered part of the comparable version. +func (v *Version) Equal(o *Version) bool { + return v.Compare(o) == 0 +} + +// Compare compares this version to another one. It returns -1, 0, or 1 if +// the version smaller, equal, or larger than the other version. +// +// Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is +// lower than the version without a prerelease. Compare always takes into account +// prereleases. If you want to work with ranges using typical range syntaxes that +// skip prereleases if the range is not looking for them use constraints. +func (v *Version) Compare(o *Version) int { + // Compare the major, minor, and patch version for differences. If a + // difference is found return the comparison. + if d := compareSegment(v.Major(), o.Major()); d != 0 { + return d + } + if d := compareSegment(v.Minor(), o.Minor()); d != 0 { + return d + } + if d := compareSegment(v.Patch(), o.Patch()); d != 0 { + return d + } + + // At this point the major, minor, and patch versions are the same. + ps := v.pre + po := o.Prerelease() + + if ps == "" && po == "" { + return 0 + } + if ps == "" { + return 1 + } + if po == "" { + return -1 + } + + return comparePrerelease(ps, po) +} + +// UnmarshalJSON implements JSON.Unmarshaler interface. +func (v *Version) UnmarshalJSON(b []byte) error { + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + temp, err := NewVersion(s) + if err != nil { + return err + } + v.major = temp.major + v.minor = temp.minor + v.patch = temp.patch + v.pre = temp.pre + v.metadata = temp.metadata + v.original = temp.original + return nil +} + +// MarshalJSON implements JSON.Marshaler interface. +func (v Version) MarshalJSON() ([]byte, error) { + return json.Marshal(v.String()) +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (v *Version) UnmarshalText(text []byte) error { + temp, err := NewVersion(string(text)) + if err != nil { + return err + } + + *v = *temp + + return nil +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (v Version) MarshalText() ([]byte, error) { + return []byte(v.String()), nil +} + +// Scan implements the SQL.Scanner interface. +func (v *Version) Scan(value interface{}) error { + var s string + s, _ = value.(string) + temp, err := NewVersion(s) + if err != nil { + return err + } + v.major = temp.major + v.minor = temp.minor + v.patch = temp.patch + v.pre = temp.pre + v.metadata = temp.metadata + v.original = temp.original + return nil +} + +// Value implements the Driver.Valuer interface. +func (v Version) Value() (driver.Value, error) { + return v.String(), nil +} + +func compareSegment(v, o uint64) int { + if v < o { + return -1 + } + if v > o { + return 1 + } + + return 0 +} + +func comparePrerelease(v, o string) int { + // split the prelease versions by their part. The separator, per the spec, + // is a . + sparts := strings.Split(v, ".") + oparts := strings.Split(o, ".") + + // Find the longer length of the parts to know how many loop iterations to + // go through. + slen := len(sparts) + olen := len(oparts) + + l := slen + if olen > slen { + l = olen + } + + // Iterate over each part of the prereleases to compare the differences. + for i := 0; i < l; i++ { + // Since the lentgh of the parts can be different we need to create + // a placeholder. This is to avoid out of bounds issues. + stemp := "" + if i < slen { + stemp = sparts[i] + } + + otemp := "" + if i < olen { + otemp = oparts[i] + } + + d := comparePrePart(stemp, otemp) + if d != 0 { + return d + } + } + + // Reaching here means two versions are of equal value but have different + // metadata (the part following a +). They are not identical in string form + // but the version comparison finds them to be equal. + return 0 +} + +func comparePrePart(s, o string) int { + // Fastpath if they are equal + if s == o { + return 0 + } + + // When s or o are empty we can use the other in an attempt to determine + // the response. + if s == "" { + if o != "" { + return -1 + } + return 1 + } + + if o == "" { + if s != "" { + return 1 + } + return -1 + } + + // When comparing strings "99" is greater than "103". To handle + // cases like this we need to detect numbers and compare them. According + // to the semver spec, numbers are always positive. If there is a - at the + // start like -99 this is to be evaluated as an alphanum. numbers always + // have precedence over alphanum. Parsing as Uints because negative numbers + // are ignored. + + oi, n1 := strconv.ParseUint(o, 10, 64) + si, n2 := strconv.ParseUint(s, 10, 64) + + // The case where both are strings compare the strings + if n1 != nil && n2 != nil { + if s > o { + return 1 + } + return -1 + } else if n1 != nil { + // o is a string and s is a number + return -1 + } else if n2 != nil { + // s is a string and o is a number + return 1 + } + // Both are numbers + if si > oi { + return 1 + } + return -1 +} + +// Like strings.ContainsAny but does an only instead of any. +func containsOnly(s string, comp string) bool { + return strings.IndexFunc(s, func(r rune) bool { + return !strings.ContainsRune(comp, r) + }) == -1 +} + +// From the spec, "Identifiers MUST comprise only +// ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. +// Numeric identifiers MUST NOT include leading zeroes.". These segments can +// be dot separated. +func validatePrerelease(p string) error { + eparts := strings.Split(p, ".") + for _, p := range eparts { + if containsOnly(p, num) { + if len(p) > 1 && p[0] == '0' { + return ErrSegmentStartsZero + } + } else if !containsOnly(p, allowed) { + return ErrInvalidPrerelease + } + } + + return nil +} + +// From the spec, "Build metadata MAY be denoted by +// appending a plus sign and a series of dot separated identifiers immediately +// following the patch or pre-release version. Identifiers MUST comprise only +// ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty." +func validateMetadata(m string) error { + eparts := strings.Split(m, ".") + for _, p := range eparts { + if !containsOnly(p, allowed) { + return ErrInvalidMetadata + } + } + return nil +} diff --git a/vendor/github.com/ansel1/merry/Makefile b/vendor/github.com/ansel1/merry/Makefile index 8e8590588c4..3a5e916f1d2 100644 --- a/vendor/github.com/ansel1/merry/Makefile +++ b/vendor/github.com/ansel1/merry/Makefile @@ -37,8 +37,7 @@ bench: ### TOOLS tools: - go get -u golang.org/x/tools/cmd/cover - go get -u golang.org/x/lint/golint + go install golang.org/x/tools/cmd/cover@latest + go install golang.org/x/lint/golint@latest .PHONY: all build lint clean fmt test coverage tools v2 - diff --git a/vendor/github.com/ansel1/merry/chainable_api.go b/vendor/github.com/ansel1/merry/chainable_api.go index e9853ded38e..3556ce70cf4 100644 --- a/vendor/github.com/ansel1/merry/chainable_api.go +++ b/vendor/github.com/ansel1/merry/chainable_api.go @@ -3,7 +3,6 @@ package merry import ( "fmt" v2 "github.com/ansel1/merry/v2" - "io" ) // Error extends the standard golang `error` interface with functions @@ -122,18 +121,7 @@ func (e *errImpl) Format(s fmt.State, verb rune) { } // should never happen, but fall back on something - switch verb { - case 'v': - if s.Flag('+') { - _, _ = io.WriteString(s, Details(e)) - return - } - fallthrough - case 's': - _, _ = io.WriteString(s, e.Error()) - case 'q': - _, _ = fmt.Fprintf(s, "%q", e.Error()) - } + v2.Format(s, verb, e) } // Error implements the error interface. diff --git a/vendor/github.com/ansel1/merry/doc.go b/vendor/github.com/ansel1/merry/doc.go index 3cd0268a5e7..d4f59ae5454 100644 --- a/vendor/github.com/ansel1/merry/doc.go +++ b/vendor/github.com/ansel1/merry/doc.go @@ -6,15 +6,15 @@ // When you create a new merry error, or wrap an existing error in a merry error, merry attaches // a stacktrace to the error: // -// err := merry.New("an error occurred") +// err := merry.New("an error occurred") // // err has a stacktrace attached. Alternately, you can wrap existing errors. merry will // attach a stacktrace at the point of wrapping: // -// _, err := ioutil.ReadAll(r) -// if err != nil { -// return merry.Wrap(err) -// } +// _, err := ioutil.ReadAll(r) +// if err != nil { +// return merry.Wrap(err) +// } // // Capturing the stack can be globally disabled with `SetStackCaptureEnabled(false)`. Wrapping // is idempotent: Wrap will only attach a stacktrace if the error doesn't already have one. @@ -23,68 +23,67 @@ // used instead, with both add a stacktrace, and augment or modify the error. For example, // Prepend() modifies the error's message (and also attaches a stacktrace): // -// _, err := ioutil.ReadAll(r) -// if err != nil { -// return merry.Prepend(err, "reading from conn failed") -// // err.Error() would read something like "reading from conn failed: timeout" -// } +// _, err := ioutil.ReadAll(r) +// if err != nil { +// return merry.Prepend(err, "reading from conn failed") +// // err.Error() would read something like "reading from conn failed: timeout" +// } // // See the other package functions for other ways to augment or modify errors, such as Append, // WithUserMessage, WithHTTPCode, WithValue, etc. These functions all return a merry.Error interface, which // has methods which mirror the package level functions, to allow simple chaining: // -// return merry.New("object not found").WithHTTPCode(404) +// return merry.New("object not found").WithHTTPCode(404) // -// Here +// # Here // // Wrap will not take a new stacktrace if an error already has one attached. Here will create // a new error which replaces the stacktrace with a new one: // -// var ErrOverflow = merry.New("overflowed") +// var ErrOverflow = merry.New("overflowed") // -// func Read() error { -// // ... -// return merry.Here(ErrOverflow) -// } +// func Read() error { +// // ... +// return merry.Here(ErrOverflow) +// } // -// Is +// # Is // // The go idiom of exporting package-level error variables for comparison to errors returned // by the package is broken by merry. For example: // -// _, err := io.ReadAll(r) -// if err == io.EOF { -// // ... -// } +// _, err := io.ReadAll(r) +// if err == io.EOF { +// // ... +// } // // If the error returned was a merry error, the equality comparison would always fail, because merry // augments errors by wrapping them in layers. To compensate for this, merry has the Is() function. // -// if merry.Is(err, io.EOF) { +// if merry.Is(err, io.EOF) { // // Is() will unwrap the err and compare each layer to the second argument. // -// Cause +// # Cause // // You can add a cause to an error: // -// if err == io.EOF { -// err = merry.New("reading failed"), err) -// fmt.Println(err.Error()) // reading failed: EOF -// } +// if err == io.EOF { +// err = merry.New("reading failed"), err) +// fmt.Println(err.Error()) // reading failed: EOF +// } // // Cause(error) will return the cause of the argument. RootCause(error) returns the innermost cause. // Is(err1, err2) is cause aware, and will return true if err2 is a cause (anywhere in the causal change) // of err1. // -// Formatting and printing +// # Formatting and printing // // To obtain an error's stacktrace, call Stack(). To get other information about the site // of the error, or print the error's stacktrace, see Location(), SourceLine(), Stacktrace(), and Details(). // // merry errors also implement the fmt.Formatter interface. errors support the following fmt flags: // -// %+v print the equivalent of Details(err), which includes the user message, full stacktrace, -// and recursively prints the details of the cause chain. -// +// %+v print the equivalent of Details(err), which includes the user message, full stacktrace, +// and recursively prints the details of the cause chain. package merry diff --git a/vendor/github.com/ansel1/merry/print.go b/vendor/github.com/ansel1/merry/print.go index 6e797a864af..76e3fac0ff3 100644 --- a/vendor/github.com/ansel1/merry/print.go +++ b/vendor/github.com/ansel1/merry/print.go @@ -9,23 +9,23 @@ import ( // be included in Details() output, if the value of that error property is not nil. // For example: // -// err := New("boom") -// err = err.WithValue(colorKey, "red") -// fmt.Println(Details(err)) +// err := New("boom") +// err = err.WithValue(colorKey, "red") +// fmt.Println(Details(err)) // -// // Output: -// // boom -// // -// // +// // Output: +// // boom +// // +// // // -// RegisterDetail("Color", colorKey) -// fmt.Println(Details(err)) +// RegisterDetail("Color", colorKey) +// fmt.Println(Details(err)) // -// // Output: -// // boom -// // Color: red -// // -// // +// // Output: +// // boom +// // Color: red +// // +// // // // Error property keys are typically not exported by the packages which define them. // Packages instead export functions which let callers access that property. diff --git a/vendor/github.com/ansel1/merry/v2/Makefile b/vendor/github.com/ansel1/merry/v2/Makefile index 992a56c424c..2d19b903c11 100644 --- a/vendor/github.com/ansel1/merry/v2/Makefile +++ b/vendor/github.com/ansel1/merry/v2/Makefile @@ -5,7 +5,7 @@ all: fmt build test lint build: go build - + lint: golint -set_exit_status ./... @@ -34,8 +34,7 @@ bench: ### TOOLS tools: - go get -u golang.org/x/tools/cmd/cover - go get -u golang.org/x/lint/golint + go install golang.org/x/tools/cmd/cover@latest + go install golang.org/x/lint/golint@latest .PHONY: all build lint clean fmt test coverage tools - diff --git a/vendor/github.com/ansel1/merry/v2/config.go b/vendor/github.com/ansel1/merry/v2/config.go index 3b42634f347..a5474fd6b50 100644 --- a/vendor/github.com/ansel1/merry/v2/config.go +++ b/vendor/github.com/ansel1/merry/v2/config.go @@ -51,28 +51,28 @@ func RegisterDetail(label string, key interface{}) { // on the error, and any non-nil values will be added to the text. // For example: // -// err := New("boom") -// err = err.WithValue(colorKey, "red") -// fmt.Println(Details(err)) +// err := New("boom") +// err = err.WithValue(colorKey, "red") +// fmt.Println(Details(err)) // -// // Output: -// // boom -// // -// // +// // Output: +// // boom +// // +// // // -// func Color(err) string { -// s, _ := Value(err, colorKey) -// return s -// } +// func Color(err) string { +// s, _ := Value(err, colorKey) +// return s +// } // -// RegisterDetailFunc("color", Color) -// fmt.Println(Details(err)) +// RegisterDetailFunc("color", Color) +// fmt.Println(Details(err)) // -// // Output: -// // boom -// // color: red -// // -// // +// // Output: +// // boom +// // color: red +// // +// // // // Error property keys are typically not exported by the packages which define them. // Packages instead export functions which let callers access that property. diff --git a/vendor/github.com/ansel1/merry/v2/doc.go b/vendor/github.com/ansel1/merry/v2/doc.go index dbd207ceb26..07def0f56ea 100644 --- a/vendor/github.com/ansel1/merry/v2/doc.go +++ b/vendor/github.com/ansel1/merry/v2/doc.go @@ -19,27 +19,27 @@ // The stack capturing feature can be turned off for better performance, though it's pretty fast. Benchmarks // on an 2017 MacBook Pro, with go 1.10: // -// BenchmarkNew_withStackCapture-8 2000000 749 ns/op -// BenchmarkNew_withoutStackCapture-8 20000000 64.1 ns/op +// BenchmarkNew_withStackCapture-8 2000000 749 ns/op +// BenchmarkNew_withoutStackCapture-8 20000000 64.1 ns/op // -// Usage +// # Usage // // This package contains functions for creating errors, or wrapping existing errors. To create: // -// err := New("boom!") -// err := Errorf("error fetching %s", filename) +// err := New("boom!") +// err := Errorf("error fetching %s", filename) // // Additional context information can be attached to errors using functional options, called Wrappers: // -// err := New("record not found", WithHTTPCode(404)) +// err := New("record not found", WithHTTPCode(404)) // // Errorf() also accepts wrappers, mixed in with the format args: // -// err := Errorf("user %s not found", username, WithHTTPCode(404)) +// err := Errorf("user %s not found", username, WithHTTPCode(404)) // // Wrappers can be applied to existing errors with Wrap(): // -// err = Wrap(err, WithHTTPCode(404)) +// err = Wrap(err, WithHTTPCode(404)) // // Wrap() will add a stacktrace to any error which doesn't already have one attached. WrapSkipping() // can be used to control where the stacktrace starts. @@ -51,16 +51,16 @@ // Errors produced by this package implement fmt.Formatter, to print additional information about the // error: // -// fmt.Printf("%v", err) // print error message and causes -// fmt.Printf("%s", err) // same as %s -// fmt.Printf("%q", err) // same as fmt.Printf("%q", err.Error()) -// fmt.Printf("%v+", err) // print Details(err) +// fmt.Printf("%v", err) // print error message and causes +// fmt.Printf("%s", err) // same as %s +// fmt.Printf("%q", err) // same as fmt.Printf("%q", err.Error()) +// fmt.Printf("%v+", err) // print Details(err) // // Details() prints the error message, all causes, the stacktrace, and additional error // values configured with RegisterDetailFunc(). By default, it will show the HTTP status // code and user message. // -// Stacktraces +// # Stacktraces // // By default, any error created by or wrapped by this package will automatically have // a stacktrace captured and attached to the error. This capture only happens if the @@ -88,7 +88,7 @@ // instances. Functions with add context (e.g. `WithValue()`) work on any `error`, and will // automatically convert them to merry errors (with a stack) if necessary. // -// Hooks +// # Hooks // // AddHooks() can install wrappers which are applied to all errors processed by this package. Hooks // are applied before any other wrappers or processing takes place. They can be used to integrate diff --git a/vendor/github.com/ansel1/merry/v2/errors.go b/vendor/github.com/ansel1/merry/v2/errors.go index 8bf35eab1a7..d9b6e2ad91d 100644 --- a/vendor/github.com/ansel1/merry/v2/errors.go +++ b/vendor/github.com/ansel1/merry/v2/errors.go @@ -23,19 +23,19 @@ func Errorf(format string, args ...interface{}) error { // to create sentinel errors, which will be wrapped with a stack later from where the // error is returned. At that time, a stack will be captured and hooks will be run. // -// var ErrNotFound = merry.Sentinel("not found", merry.WithHTTPCode(404)) +// var ErrNotFound = merry.Sentinel("not found", merry.WithHTTPCode(404)) // -// func FindUser(name string) (*User, error) { -// // some db code which fails to find a user -// return nil, merry.Wrap(ErrNotFound) -// } +// func FindUser(name string) (*User, error) { +// // some db code which fails to find a user +// return nil, merry.Wrap(ErrNotFound) +// } // -// func main() { -// _, err := FindUser("bob") -// fmt.Println(errors.Is(err, ErrNotFound) // "true" -// fmt.Println(merry.Details(err)) // stacktrace will start at the return statement -// // in FindUser() -// } +// func main() { +// _, err := FindUser("bob") +// fmt.Println(errors.Is(err, ErrNotFound) // "true" +// fmt.Println(merry.Details(err)) // stacktrace will start at the return statement +// // in FindUser() +// } func Sentinel(msg string, wrappers ...Wrapper) error { return ApplySkipping(errors.New(msg), 1, wrappers...) } @@ -93,7 +93,15 @@ func WrapSkipping(err error, skip int, wrappers ...Wrapper) error { } err = ApplySkipping(err, skip+1, hooks...) err = ApplySkipping(err, skip+1, wrappers...) - return captureStack(err, skip+1, false) + err = captureStack(err, skip+1, false) + + // ensure the resulting error implements Formatter + // https://github.com/ansel1/merry/issues/26 + if _, ok := err.(fmt.Formatter); !ok { + err = &formatError{err} + } + + return err } // Apply is like Wrap, but does not execute hooks or do automatic stack capture. It just @@ -113,6 +121,7 @@ func ApplySkipping(err error, skip int, wrappers ...Wrapper) error { for _, w := range wrappers { err = w.Wrap(err, skip+1) } + return err } diff --git a/vendor/github.com/ansel1/merry/v2/impl.go b/vendor/github.com/ansel1/merry/v2/impl.go index 77844373876..6cb99530f23 100644 --- a/vendor/github.com/ansel1/merry/v2/impl.go +++ b/vendor/github.com/ansel1/merry/v2/impl.go @@ -37,6 +37,26 @@ func (e errKey) String() string { } } +// formatError adds a Format implementation to an error. +type formatError struct { + error +} + +// Format implements fmt.Formatter +func (e *formatError) Format(s fmt.State, verb rune) { + Format(s, verb, e) +} + +// String implements fmt.Stringer +func (e *formatError) String() string { + return e.Error() +} + +// Unwrap returns the next wrapped error. +func (e *formatError) Unwrap() error { + return e.error +} + type errWithValue struct { err error key, value interface{} @@ -120,7 +140,7 @@ func (e *errWithCause) Format(f fmt.State, verb rune) { Format(f, verb, e) } -// errWithCause needs to provide custome implementations of Is and As. +// errWithCause needs to provide custom implementations of Is and As. // errors.Is() doesn't work on errWithCause because error.Is() uses errors.Unwrap() to traverse the error // chain. But errWithCause.Unwrap() doesn't return the next error in the chain. Instead, // it wraps the next error in a shim. The standard Is/As tests would compare the shim to the target. diff --git a/vendor/github.com/ansel1/merry/v2/print.go b/vendor/github.com/ansel1/merry/v2/print.go index b940aeb6d51..6f39e039a26 100644 --- a/vendor/github.com/ansel1/merry/v2/print.go +++ b/vendor/github.com/ansel1/merry/v2/print.go @@ -111,10 +111,9 @@ func Details(e error) string { // Format adapts errors to fmt.Formatter interface. It's intended to be used // help error impls implement fmt.Formatter, e.g.: // -// func (e *myErr) Format(f fmt.State, verb rune) { -// Format(f, verb, e) -// } -// +// func (e *myErr) Format(f fmt.State, verb rune) { +// Format(f, verb, e) +// } func Format(s fmt.State, verb rune, err error) { switch verb { case 'v': diff --git a/vendor/github.com/ansel1/merry/v2/wrappers.go b/vendor/github.com/ansel1/merry/v2/wrappers.go index c585888855a..84c984feaa7 100644 --- a/vendor/github.com/ansel1/merry/v2/wrappers.go +++ b/vendor/github.com/ansel1/merry/v2/wrappers.go @@ -150,11 +150,13 @@ func CaptureStack(force bool) Wrapper { // WithCause sets one error as the cause of another error. This is useful for associating errors // from lower API levels with sentinel errors in higher API levels. errors.Is() and errors.As() -// will traverse both the main chain of error wrappers, as well as down the chain of causes. +// will traverse both the main chain of error wrappers, and down the chain of causes. +// +// If err is nil, this is a no-op func WithCause(err error) Wrapper { return WrapperFunc(func(nerr error, _ int) error { - if nerr == nil { - return nil + if nerr == nil || err == nil { + return nerr } return &errWithCause{err: nerr, cause: err} }) @@ -165,12 +167,6 @@ func WithCause(err error) Wrapper { // other processing. It is mainly intended as a primitive for writing Wrapper implementations. // // if err is nil, returns nil. -// -// Keeping this private for now. If it proves useful, it may be made public later, but -// for now, external packages can get the same behavor with this: -// -// WithValue(key, value).Wrap(err) -// func Set(err error, key, value interface{}) error { if err == nil { return nil diff --git a/vendor/github.com/containernetworking/cni/LICENSE b/vendor/github.com/containernetworking/cni/LICENSE new file mode 100644 index 00000000000..8dada3edaf5 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/containernetworking/cni/libcni/api.go b/vendor/github.com/containernetworking/cni/libcni/api.go new file mode 100644 index 00000000000..5c7f3b028c0 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/libcni/api.go @@ -0,0 +1,877 @@ +// Copyright 2015 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package libcni + +// Note this is the actual implementation of the CNI specification, which +// is reflected in the SPEC.md file. +// it is typically bundled into runtime providers (i.e. containerd or cri-o would use this +// before calling runc or hcsshim). It is also bundled into CNI providers as well, for example, +// to add an IP to a container, to parse the configuration of the CNI and so on. + +import ( + "context" + "encoding/json" + "fmt" + "os" + "path/filepath" + "sort" + "strings" + + "github.com/containernetworking/cni/pkg/invoke" + "github.com/containernetworking/cni/pkg/types" + "github.com/containernetworking/cni/pkg/types/create" + "github.com/containernetworking/cni/pkg/utils" + "github.com/containernetworking/cni/pkg/version" +) + +var ( + CacheDir = "/var/lib/cni" + // slightly awkward wording to preserve anyone matching on error strings + ErrorCheckNotSupp = fmt.Errorf("does not support the CHECK command") +) + +const ( + CNICacheV1 = "cniCacheV1" +) + +// A RuntimeConf holds the arguments to one invocation of a CNI plugin +// excepting the network configuration, with the nested exception that +// the `runtimeConfig` from the network configuration is included +// here. +type RuntimeConf struct { + ContainerID string + NetNS string + IfName string + Args [][2]string + // A dictionary of capability-specific data passed by the runtime + // to plugins as top-level keys in the 'runtimeConfig' dictionary + // of the plugin's stdin data. libcni will ensure that only keys + // in this map which match the capabilities of the plugin are passed + // to the plugin + CapabilityArgs map[string]interface{} + + // DEPRECATED. Will be removed in a future release. + CacheDir string +} + +type NetworkConfig struct { + Network *types.NetConf + Bytes []byte +} + +type NetworkConfigList struct { + Name string + CNIVersion string + DisableCheck bool + Plugins []*NetworkConfig + Bytes []byte +} + +type NetworkAttachment struct { + ContainerID string + Network string + IfName string + Config []byte + NetNS string + CniArgs [][2]string + CapabilityArgs map[string]interface{} +} + +type GCArgs struct { + ValidAttachments []types.GCAttachment +} + +type CNI interface { + AddNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) (types.Result, error) + CheckNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error + DelNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error + GetNetworkListCachedResult(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error) + GetNetworkListCachedConfig(net *NetworkConfigList, rt *RuntimeConf) ([]byte, *RuntimeConf, error) + + AddNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) (types.Result, error) + CheckNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error + DelNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error + GetNetworkCachedResult(net *NetworkConfig, rt *RuntimeConf) (types.Result, error) + GetNetworkCachedConfig(net *NetworkConfig, rt *RuntimeConf) ([]byte, *RuntimeConf, error) + + ValidateNetworkList(ctx context.Context, net *NetworkConfigList) ([]string, error) + ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error) + + GCNetworkList(ctx context.Context, net *NetworkConfigList, args *GCArgs) error + GetStatusNetworkList(ctx context.Context, net *NetworkConfigList) error + + GetCachedAttachments(containerID string) ([]*NetworkAttachment, error) +} + +type CNIConfig struct { + Path []string + exec invoke.Exec + cacheDir string +} + +// CNIConfig implements the CNI interface +var _ CNI = &CNIConfig{} + +// NewCNIConfig returns a new CNIConfig object that will search for plugins +// in the given paths and use the given exec interface to run those plugins, +// or if the exec interface is not given, will use a default exec handler. +func NewCNIConfig(path []string, exec invoke.Exec) *CNIConfig { + return NewCNIConfigWithCacheDir(path, "", exec) +} + +// NewCNIConfigWithCacheDir returns a new CNIConfig object that will search for plugins +// in the given paths use the given exec interface to run those plugins, +// or if the exec interface is not given, will use a default exec handler. +// The given cache directory will be used for temporary data storage when needed. +func NewCNIConfigWithCacheDir(path []string, cacheDir string, exec invoke.Exec) *CNIConfig { + return &CNIConfig{ + Path: path, + cacheDir: cacheDir, + exec: exec, + } +} + +func buildOneConfig(name, cniVersion string, orig *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (*NetworkConfig, error) { + var err error + + inject := map[string]interface{}{ + "name": name, + "cniVersion": cniVersion, + } + // Add previous plugin result + if prevResult != nil { + inject["prevResult"] = prevResult + } + + // Ensure every config uses the same name and version + orig, err = InjectConf(orig, inject) + if err != nil { + return nil, err + } + if rt != nil { + return injectRuntimeConfig(orig, rt) + } + + return orig, nil +} + +// This function takes a libcni RuntimeConf structure and injects values into +// a "runtimeConfig" dictionary in the CNI network configuration JSON that +// will be passed to the plugin on stdin. +// +// Only "capabilities arguments" passed by the runtime are currently injected. +// These capabilities arguments are filtered through the plugin's advertised +// capabilities from its config JSON, and any keys in the CapabilityArgs +// matching plugin capabilities are added to the "runtimeConfig" dictionary +// sent to the plugin via JSON on stdin. For example, if the plugin's +// capabilities include "portMappings", and the CapabilityArgs map includes a +// "portMappings" key, that key and its value are added to the "runtimeConfig" +// dictionary to be passed to the plugin's stdin. +func injectRuntimeConfig(orig *NetworkConfig, rt *RuntimeConf) (*NetworkConfig, error) { + var err error + + rc := make(map[string]interface{}) + for capability, supported := range orig.Network.Capabilities { + if !supported { + continue + } + if data, ok := rt.CapabilityArgs[capability]; ok { + rc[capability] = data + } + } + + if len(rc) > 0 { + orig, err = InjectConf(orig, map[string]interface{}{"runtimeConfig": rc}) + if err != nil { + return nil, err + } + } + + return orig, nil +} + +// ensure we have a usable exec if the CNIConfig was not given one +func (c *CNIConfig) ensureExec() invoke.Exec { + if c.exec == nil { + c.exec = &invoke.DefaultExec{ + RawExec: &invoke.RawExec{Stderr: os.Stderr}, + PluginDecoder: version.PluginDecoder{}, + } + } + return c.exec +} + +type cachedInfo struct { + Kind string `json:"kind"` + ContainerID string `json:"containerId"` + Config []byte `json:"config"` + IfName string `json:"ifName"` + NetworkName string `json:"networkName"` + NetNS string `json:"netns,omitempty"` + CniArgs [][2]string `json:"cniArgs,omitempty"` + CapabilityArgs map[string]interface{} `json:"capabilityArgs,omitempty"` + RawResult map[string]interface{} `json:"result,omitempty"` + Result types.Result `json:"-"` +} + +// getCacheDir returns the cache directory in this order: +// 1) global cacheDir from CNIConfig object +// 2) deprecated cacheDir from RuntimeConf object +// 3) fall back to default cache directory +func (c *CNIConfig) getCacheDir(rt *RuntimeConf) string { + if c.cacheDir != "" { + return c.cacheDir + } + if rt.CacheDir != "" { + return rt.CacheDir + } + return CacheDir +} + +func (c *CNIConfig) getCacheFilePath(netName string, rt *RuntimeConf) (string, error) { + if netName == "" || rt.ContainerID == "" || rt.IfName == "" { + return "", fmt.Errorf("cache file path requires network name (%q), container ID (%q), and interface name (%q)", netName, rt.ContainerID, rt.IfName) + } + return filepath.Join(c.getCacheDir(rt), "results", fmt.Sprintf("%s-%s-%s", netName, rt.ContainerID, rt.IfName)), nil +} + +func (c *CNIConfig) cacheAdd(result types.Result, config []byte, netName string, rt *RuntimeConf) error { + cached := cachedInfo{ + Kind: CNICacheV1, + ContainerID: rt.ContainerID, + Config: config, + IfName: rt.IfName, + NetworkName: netName, + NetNS: rt.NetNS, + CniArgs: rt.Args, + CapabilityArgs: rt.CapabilityArgs, + } + + // We need to get type.Result into cachedInfo as JSON map + // Marshal to []byte, then Unmarshal into cached.RawResult + data, err := json.Marshal(result) + if err != nil { + return err + } + + err = json.Unmarshal(data, &cached.RawResult) + if err != nil { + return err + } + + newBytes, err := json.Marshal(&cached) + if err != nil { + return err + } + + fname, err := c.getCacheFilePath(netName, rt) + if err != nil { + return err + } + if err := os.MkdirAll(filepath.Dir(fname), 0o700); err != nil { + return err + } + + return os.WriteFile(fname, newBytes, 0o600) +} + +func (c *CNIConfig) cacheDel(netName string, rt *RuntimeConf) error { + fname, err := c.getCacheFilePath(netName, rt) + if err != nil { + // Ignore error + return nil + } + return os.Remove(fname) +} + +func (c *CNIConfig) getCachedConfig(netName string, rt *RuntimeConf) ([]byte, *RuntimeConf, error) { + var bytes []byte + + fname, err := c.getCacheFilePath(netName, rt) + if err != nil { + return nil, nil, err + } + bytes, err = os.ReadFile(fname) + if err != nil { + // Ignore read errors; the cached result may not exist on-disk + return nil, nil, nil + } + + unmarshaled := cachedInfo{} + if err := json.Unmarshal(bytes, &unmarshaled); err != nil { + return nil, nil, fmt.Errorf("failed to unmarshal cached network %q config: %w", netName, err) + } + if unmarshaled.Kind != CNICacheV1 { + return nil, nil, fmt.Errorf("read cached network %q config has wrong kind: %v", netName, unmarshaled.Kind) + } + + newRt := *rt + if unmarshaled.CniArgs != nil { + newRt.Args = unmarshaled.CniArgs + } + newRt.CapabilityArgs = unmarshaled.CapabilityArgs + + return unmarshaled.Config, &newRt, nil +} + +func (c *CNIConfig) getLegacyCachedResult(netName, cniVersion string, rt *RuntimeConf) (types.Result, error) { + fname, err := c.getCacheFilePath(netName, rt) + if err != nil { + return nil, err + } + data, err := os.ReadFile(fname) + if err != nil { + // Ignore read errors; the cached result may not exist on-disk + return nil, nil + } + + // Load the cached result + result, err := create.CreateFromBytes(data) + if err != nil { + return nil, err + } + + // Convert to the config version to ensure plugins get prevResult + // in the same version as the config. The cached result version + // should match the config version unless the config was changed + // while the container was running. + result, err = result.GetAsVersion(cniVersion) + if err != nil { + return nil, fmt.Errorf("failed to convert cached result to config version %q: %w", cniVersion, err) + } + return result, nil +} + +func (c *CNIConfig) getCachedResult(netName, cniVersion string, rt *RuntimeConf) (types.Result, error) { + fname, err := c.getCacheFilePath(netName, rt) + if err != nil { + return nil, err + } + fdata, err := os.ReadFile(fname) + if err != nil { + // Ignore read errors; the cached result may not exist on-disk + return nil, nil + } + + cachedInfo := cachedInfo{} + if err := json.Unmarshal(fdata, &cachedInfo); err != nil || cachedInfo.Kind != CNICacheV1 { + return c.getLegacyCachedResult(netName, cniVersion, rt) + } + + newBytes, err := json.Marshal(&cachedInfo.RawResult) + if err != nil { + return nil, fmt.Errorf("failed to marshal cached network %q config: %w", netName, err) + } + + // Load the cached result + result, err := create.CreateFromBytes(newBytes) + if err != nil { + return nil, err + } + + // Convert to the config version to ensure plugins get prevResult + // in the same version as the config. The cached result version + // should match the config version unless the config was changed + // while the container was running. + result, err = result.GetAsVersion(cniVersion) + if err != nil { + return nil, fmt.Errorf("failed to convert cached result to config version %q: %w", cniVersion, err) + } + return result, nil +} + +// GetNetworkListCachedResult returns the cached Result of the previous +// AddNetworkList() operation for a network list, or an error. +func (c *CNIConfig) GetNetworkListCachedResult(list *NetworkConfigList, rt *RuntimeConf) (types.Result, error) { + return c.getCachedResult(list.Name, list.CNIVersion, rt) +} + +// GetNetworkCachedResult returns the cached Result of the previous +// AddNetwork() operation for a network, or an error. +func (c *CNIConfig) GetNetworkCachedResult(net *NetworkConfig, rt *RuntimeConf) (types.Result, error) { + return c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt) +} + +// GetNetworkListCachedConfig copies the input RuntimeConf to output +// RuntimeConf with fields updated with info from the cached Config. +func (c *CNIConfig) GetNetworkListCachedConfig(list *NetworkConfigList, rt *RuntimeConf) ([]byte, *RuntimeConf, error) { + return c.getCachedConfig(list.Name, rt) +} + +// GetNetworkCachedConfig copies the input RuntimeConf to output +// RuntimeConf with fields updated with info from the cached Config. +func (c *CNIConfig) GetNetworkCachedConfig(net *NetworkConfig, rt *RuntimeConf) ([]byte, *RuntimeConf, error) { + return c.getCachedConfig(net.Network.Name, rt) +} + +// GetCachedAttachments returns a list of network attachments from the cache. +// The returned list will be filtered by the containerID if the value is not empty. +func (c *CNIConfig) GetCachedAttachments(containerID string) ([]*NetworkAttachment, error) { + dirPath := filepath.Join(c.getCacheDir(&RuntimeConf{}), "results") + entries, err := os.ReadDir(dirPath) + if err != nil { + return nil, err + } + + fileNames := make([]string, 0, len(entries)) + for _, e := range entries { + fileNames = append(fileNames, e.Name()) + } + sort.Strings(fileNames) + + attachments := []*NetworkAttachment{} + for _, fname := range fileNames { + if len(containerID) > 0 { + part := fmt.Sprintf("-%s-", containerID) + pos := strings.Index(fname, part) + if pos <= 0 || pos+len(part) >= len(fname) { + continue + } + } + + cacheFile := filepath.Join(dirPath, fname) + bytes, err := os.ReadFile(cacheFile) + if err != nil { + continue + } + + cachedInfo := cachedInfo{} + + if err := json.Unmarshal(bytes, &cachedInfo); err != nil { + continue + } + if cachedInfo.Kind != CNICacheV1 { + continue + } + if len(containerID) > 0 && cachedInfo.ContainerID != containerID { + continue + } + if cachedInfo.IfName == "" || cachedInfo.NetworkName == "" { + continue + } + + attachments = append(attachments, &NetworkAttachment{ + ContainerID: cachedInfo.ContainerID, + Network: cachedInfo.NetworkName, + IfName: cachedInfo.IfName, + Config: cachedInfo.Config, + NetNS: cachedInfo.NetNS, + CniArgs: cachedInfo.CniArgs, + CapabilityArgs: cachedInfo.CapabilityArgs, + }) + } + return attachments, nil +} + +func (c *CNIConfig) addNetwork(ctx context.Context, name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (types.Result, error) { + c.ensureExec() + pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path) + if err != nil { + return nil, err + } + if err := utils.ValidateContainerID(rt.ContainerID); err != nil { + return nil, err + } + if err := utils.ValidateNetworkName(name); err != nil { + return nil, err + } + if err := utils.ValidateInterfaceName(rt.IfName); err != nil { + return nil, err + } + + newConf, err := buildOneConfig(name, cniVersion, net, prevResult, rt) + if err != nil { + return nil, err + } + + return invoke.ExecPluginWithResult(ctx, pluginPath, newConf.Bytes, c.args("ADD", rt), c.exec) +} + +// AddNetworkList executes a sequence of plugins with the ADD command +func (c *CNIConfig) AddNetworkList(ctx context.Context, list *NetworkConfigList, rt *RuntimeConf) (types.Result, error) { + var err error + var result types.Result + for _, net := range list.Plugins { + result, err = c.addNetwork(ctx, list.Name, list.CNIVersion, net, result, rt) + if err != nil { + return nil, fmt.Errorf("plugin %s failed (add): %w", pluginDescription(net.Network), err) + } + } + + if err = c.cacheAdd(result, list.Bytes, list.Name, rt); err != nil { + return nil, fmt.Errorf("failed to set network %q cached result: %w", list.Name, err) + } + + return result, nil +} + +func (c *CNIConfig) checkNetwork(ctx context.Context, name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) error { + c.ensureExec() + pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path) + if err != nil { + return err + } + + newConf, err := buildOneConfig(name, cniVersion, net, prevResult, rt) + if err != nil { + return err + } + + return invoke.ExecPluginWithoutResult(ctx, pluginPath, newConf.Bytes, c.args("CHECK", rt), c.exec) +} + +// CheckNetworkList executes a sequence of plugins with the CHECK command +func (c *CNIConfig) CheckNetworkList(ctx context.Context, list *NetworkConfigList, rt *RuntimeConf) error { + // CHECK was added in CNI spec version 0.4.0 and higher + if gtet, err := version.GreaterThanOrEqualTo(list.CNIVersion, "0.4.0"); err != nil { + return err + } else if !gtet { + return fmt.Errorf("configuration version %q %w", list.CNIVersion, ErrorCheckNotSupp) + } + + if list.DisableCheck { + return nil + } + + cachedResult, err := c.getCachedResult(list.Name, list.CNIVersion, rt) + if err != nil { + return fmt.Errorf("failed to get network %q cached result: %w", list.Name, err) + } + + for _, net := range list.Plugins { + if err := c.checkNetwork(ctx, list.Name, list.CNIVersion, net, cachedResult, rt); err != nil { + return err + } + } + + return nil +} + +func (c *CNIConfig) delNetwork(ctx context.Context, name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) error { + c.ensureExec() + pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path) + if err != nil { + return err + } + + newConf, err := buildOneConfig(name, cniVersion, net, prevResult, rt) + if err != nil { + return err + } + + return invoke.ExecPluginWithoutResult(ctx, pluginPath, newConf.Bytes, c.args("DEL", rt), c.exec) +} + +// DelNetworkList executes a sequence of plugins with the DEL command +func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList, rt *RuntimeConf) error { + var cachedResult types.Result + + // Cached result on DEL was added in CNI spec version 0.4.0 and higher + if gtet, err := version.GreaterThanOrEqualTo(list.CNIVersion, "0.4.0"); err != nil { + return err + } else if gtet { + if cachedResult, err = c.getCachedResult(list.Name, list.CNIVersion, rt); err != nil { + _ = c.cacheDel(list.Name, rt) + cachedResult = nil + } + } + + for i := len(list.Plugins) - 1; i >= 0; i-- { + net := list.Plugins[i] + if err := c.delNetwork(ctx, list.Name, list.CNIVersion, net, cachedResult, rt); err != nil { + return fmt.Errorf("plugin %s failed (delete): %w", pluginDescription(net.Network), err) + } + } + + if cachedResult != nil { + _ = c.cacheDel(list.Name, rt) + } + + return nil +} + +func pluginDescription(net *types.NetConf) string { + if net == nil { + return "" + } + pluginType := net.Type + out := fmt.Sprintf("type=%q", pluginType) + name := net.Name + if name != "" { + out += fmt.Sprintf(" name=%q", name) + } + return out +} + +// AddNetwork executes the plugin with the ADD command +func (c *CNIConfig) AddNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) (types.Result, error) { + result, err := c.addNetwork(ctx, net.Network.Name, net.Network.CNIVersion, net, nil, rt) + if err != nil { + return nil, err + } + + if err = c.cacheAdd(result, net.Bytes, net.Network.Name, rt); err != nil { + return nil, fmt.Errorf("failed to set network %q cached result: %w", net.Network.Name, err) + } + + return result, nil +} + +// CheckNetwork executes the plugin with the CHECK command +func (c *CNIConfig) CheckNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error { + // CHECK was added in CNI spec version 0.4.0 and higher + if gtet, err := version.GreaterThanOrEqualTo(net.Network.CNIVersion, "0.4.0"); err != nil { + return err + } else if !gtet { + return fmt.Errorf("configuration version %q %w", net.Network.CNIVersion, ErrorCheckNotSupp) + } + + cachedResult, err := c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt) + if err != nil { + return fmt.Errorf("failed to get network %q cached result: %w", net.Network.Name, err) + } + return c.checkNetwork(ctx, net.Network.Name, net.Network.CNIVersion, net, cachedResult, rt) +} + +// DelNetwork executes the plugin with the DEL command +func (c *CNIConfig) DelNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error { + var cachedResult types.Result + + // Cached result on DEL was added in CNI spec version 0.4.0 and higher + if gtet, err := version.GreaterThanOrEqualTo(net.Network.CNIVersion, "0.4.0"); err != nil { + return err + } else if gtet { + cachedResult, err = c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt) + if err != nil { + return fmt.Errorf("failed to get network %q cached result: %w", net.Network.Name, err) + } + } + + if err := c.delNetwork(ctx, net.Network.Name, net.Network.CNIVersion, net, cachedResult, rt); err != nil { + return err + } + _ = c.cacheDel(net.Network.Name, rt) + return nil +} + +// ValidateNetworkList checks that a configuration is reasonably valid. +// - all the specified plugins exist on disk +// - every plugin supports the desired version. +// +// Returns a list of all capabilities supported by the configuration, or error +func (c *CNIConfig) ValidateNetworkList(ctx context.Context, list *NetworkConfigList) ([]string, error) { + version := list.CNIVersion + + // holding map for seen caps (in case of duplicates) + caps := map[string]interface{}{} + + errs := []error{} + for _, net := range list.Plugins { + if err := c.validatePlugin(ctx, net.Network.Type, version); err != nil { + errs = append(errs, err) + } + for c, enabled := range net.Network.Capabilities { + if !enabled { + continue + } + caps[c] = struct{}{} + } + } + + if len(errs) > 0 { + return nil, fmt.Errorf("%v", errs) + } + + // make caps list + cc := make([]string, 0, len(caps)) + for c := range caps { + cc = append(cc, c) + } + + return cc, nil +} + +// ValidateNetwork checks that a configuration is reasonably valid. +// It uses the same logic as ValidateNetworkList) +// Returns a list of capabilities +func (c *CNIConfig) ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error) { + caps := []string{} + for c, ok := range net.Network.Capabilities { + if ok { + caps = append(caps, c) + } + } + if err := c.validatePlugin(ctx, net.Network.Type, net.Network.CNIVersion); err != nil { + return nil, err + } + return caps, nil +} + +// validatePlugin checks that an individual plugin's configuration is sane +func (c *CNIConfig) validatePlugin(ctx context.Context, pluginName, expectedVersion string) error { + c.ensureExec() + pluginPath, err := c.exec.FindInPath(pluginName, c.Path) + if err != nil { + return err + } + if expectedVersion == "" { + expectedVersion = "0.1.0" + } + + vi, err := invoke.GetVersionInfo(ctx, pluginPath, c.exec) + if err != nil { + return err + } + for _, vers := range vi.SupportedVersions() { + if vers == expectedVersion { + return nil + } + } + return fmt.Errorf("plugin %s does not support config version %q", pluginName, expectedVersion) +} + +// GetVersionInfo reports which versions of the CNI spec are supported by +// the given plugin. +func (c *CNIConfig) GetVersionInfo(ctx context.Context, pluginType string) (version.PluginInfo, error) { + c.ensureExec() + pluginPath, err := c.exec.FindInPath(pluginType, c.Path) + if err != nil { + return nil, err + } + + return invoke.GetVersionInfo(ctx, pluginPath, c.exec) +} + +// GCNetworkList will do two things +// - dump the list of cached attachments, and issue deletes as necessary +// - issue a GC to the underlying plugins (if the version is high enough) +func (c *CNIConfig) GCNetworkList(ctx context.Context, list *NetworkConfigList, args *GCArgs) error { + // First, get the list of cached attachments + cachedAttachments, err := c.GetCachedAttachments("") + if err != nil { + return nil + } + + validAttachments := make(map[types.GCAttachment]interface{}, len(args.ValidAttachments)) + for _, a := range args.ValidAttachments { + validAttachments[a] = nil + } + + var errs []error + + for _, cachedAttachment := range cachedAttachments { + if cachedAttachment.Network != list.Name { + continue + } + // we found this attachment + gca := types.GCAttachment{ + ContainerID: cachedAttachment.ContainerID, + IfName: cachedAttachment.IfName, + } + if _, ok := validAttachments[gca]; ok { + continue + } + // otherwise, this attachment wasn't valid and we should issue a CNI DEL + rt := RuntimeConf{ + ContainerID: cachedAttachment.ContainerID, + NetNS: cachedAttachment.NetNS, + IfName: cachedAttachment.IfName, + Args: cachedAttachment.CniArgs, + CapabilityArgs: cachedAttachment.CapabilityArgs, + } + if err := c.DelNetworkList(ctx, list, &rt); err != nil { + errs = append(errs, fmt.Errorf("failed to delete stale attachment %s %s: %w", rt.ContainerID, rt.IfName, err)) + } + } + + // now, if the version supports it, issue a GC + if gt, _ := version.GreaterThanOrEqualTo(list.CNIVersion, "1.1.0"); gt { + inject := map[string]interface{}{ + "name": list.Name, + "cniVersion": list.CNIVersion, + "cni.dev/valid-attachments": args.ValidAttachments, + } + for _, plugin := range list.Plugins { + // build config here + pluginConfig, err := InjectConf(plugin, inject) + if err != nil { + errs = append(errs, fmt.Errorf("failed to generate configuration to GC plugin %s: %w", plugin.Network.Type, err)) + } + if err := c.gcNetwork(ctx, pluginConfig); err != nil { + errs = append(errs, fmt.Errorf("failed to GC plugin %s: %w", plugin.Network.Type, err)) + } + } + } + + return joinErrors(errs...) +} + +func (c *CNIConfig) gcNetwork(ctx context.Context, net *NetworkConfig) error { + c.ensureExec() + pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path) + if err != nil { + return err + } + args := c.args("GC", &RuntimeConf{}) + + return invoke.ExecPluginWithoutResult(ctx, pluginPath, net.Bytes, args, c.exec) +} + +func (c *CNIConfig) GetStatusNetworkList(ctx context.Context, list *NetworkConfigList) error { + // If the version doesn't support status, abort. + if gt, _ := version.GreaterThanOrEqualTo(list.CNIVersion, "1.1.0"); !gt { + return nil + } + + inject := map[string]interface{}{ + "name": list.Name, + "cniVersion": list.CNIVersion, + } + + for _, plugin := range list.Plugins { + // build config here + pluginConfig, err := InjectConf(plugin, inject) + if err != nil { + return fmt.Errorf("failed to generate configuration to get plugin STATUS %s: %w", plugin.Network.Type, err) + } + if err := c.getStatusNetwork(ctx, pluginConfig); err != nil { + return err // Don't collect errors here, so we return a clean error code. + } + } + return nil +} + +func (c *CNIConfig) getStatusNetwork(ctx context.Context, net *NetworkConfig) error { + c.ensureExec() + pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path) + if err != nil { + return err + } + args := c.args("STATUS", &RuntimeConf{}) + + return invoke.ExecPluginWithoutResult(ctx, pluginPath, net.Bytes, args, c.exec) +} + +// ===== +func (c *CNIConfig) args(action string, rt *RuntimeConf) *invoke.Args { + return &invoke.Args{ + Command: action, + ContainerID: rt.ContainerID, + NetNS: rt.NetNS, + PluginArgs: rt.Args, + IfName: rt.IfName, + Path: strings.Join(c.Path, string(os.PathListSeparator)), + } +} diff --git a/vendor/github.com/containernetworking/cni/libcni/conf.go b/vendor/github.com/containernetworking/cni/libcni/conf.go new file mode 100644 index 00000000000..6c5d99de982 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/libcni/conf.go @@ -0,0 +1,327 @@ +// Copyright 2015 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package libcni + +import ( + "encoding/json" + "errors" + "fmt" + "os" + "path/filepath" + "sort" + "strings" + + "github.com/Masterminds/semver/v3" + + "github.com/containernetworking/cni/pkg/types" + "github.com/containernetworking/cni/pkg/version" +) + +type NotFoundError struct { + Dir string + Name string +} + +func (e NotFoundError) Error() string { + return fmt.Sprintf(`no net configuration with name "%s" in %s`, e.Name, e.Dir) +} + +type NoConfigsFoundError struct { + Dir string +} + +func (e NoConfigsFoundError) Error() string { + return fmt.Sprintf(`no net configurations found in %s`, e.Dir) +} + +func ConfFromBytes(bytes []byte) (*NetworkConfig, error) { + conf := &NetworkConfig{Bytes: bytes, Network: &types.NetConf{}} + if err := json.Unmarshal(bytes, conf.Network); err != nil { + return nil, fmt.Errorf("error parsing configuration: %w", err) + } + if conf.Network.Type == "" { + return nil, fmt.Errorf("error parsing configuration: missing 'type'") + } + return conf, nil +} + +func ConfFromFile(filename string) (*NetworkConfig, error) { + bytes, err := os.ReadFile(filename) + if err != nil { + return nil, fmt.Errorf("error reading %s: %w", filename, err) + } + return ConfFromBytes(bytes) +} + +func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) { + rawList := make(map[string]interface{}) + if err := json.Unmarshal(bytes, &rawList); err != nil { + return nil, fmt.Errorf("error parsing configuration list: %w", err) + } + + rawName, ok := rawList["name"] + if !ok { + return nil, fmt.Errorf("error parsing configuration list: no name") + } + name, ok := rawName.(string) + if !ok { + return nil, fmt.Errorf("error parsing configuration list: invalid name type %T", rawName) + } + + var cniVersion string + rawVersion, ok := rawList["cniVersion"] + if ok { + cniVersion, ok = rawVersion.(string) + if !ok { + return nil, fmt.Errorf("error parsing configuration list: invalid cniVersion type %T", rawVersion) + } + } + + rawVersions, ok := rawList["cniVersions"] + if ok { + // Parse the current package CNI version + currentVersion, err := semver.NewVersion(version.Current()) + if err != nil { + panic("CNI version is invalid semver!") + } + + rvs, ok := rawVersions.([]interface{}) + if !ok { + return nil, fmt.Errorf("error parsing configuration list: invalid type for cniVersions: %T", rvs) + } + vs := make([]*semver.Version, 0, len(rvs)) + for i, rv := range rvs { + v, ok := rv.(string) + if !ok { + return nil, fmt.Errorf("error parsing configuration list: invalid type for cniVersions index %d: %T", i, rv) + } + if v, err := semver.NewVersion(v); err != nil { + return nil, fmt.Errorf("error parsing configuration list: invalid cniVersions entry %s at index %d: %w", v, i, err) + } else if !v.GreaterThan(currentVersion) { + // Skip versions "greater" than this implementation of the spec + vs = append(vs, v) + } + } + + // if cniVersion was already set, append it to the list for sorting. + if cniVersion != "" { + if v, err := semver.NewVersion(cniVersion); err != nil { + return nil, fmt.Errorf("error parsing configuration list: invalid cniVersion %s: %w", cniVersion, err) + } else if !v.GreaterThan(currentVersion) { + // ignore any versions higher than the current implemented spec version + vs = append(vs, v) + } + } + sort.Sort(semver.Collection(vs)) + if len(vs) > 0 { + cniVersion = vs[len(vs)-1].String() + } + } + + disableCheck := false + if rawDisableCheck, ok := rawList["disableCheck"]; ok { + disableCheck, ok = rawDisableCheck.(bool) + if !ok { + disableCheckStr, ok := rawDisableCheck.(string) + if !ok { + return nil, fmt.Errorf("error parsing configuration list: invalid disableCheck type %T", rawDisableCheck) + } + switch { + case strings.ToLower(disableCheckStr) == "false": + disableCheck = false + case strings.ToLower(disableCheckStr) == "true": + disableCheck = true + default: + return nil, fmt.Errorf("error parsing configuration list: invalid disableCheck value %q", disableCheckStr) + } + } + } + + list := &NetworkConfigList{ + Name: name, + DisableCheck: disableCheck, + CNIVersion: cniVersion, + Bytes: bytes, + } + + var plugins []interface{} + plug, ok := rawList["plugins"] + if !ok { + return nil, fmt.Errorf("error parsing configuration list: no 'plugins' key") + } + plugins, ok = plug.([]interface{}) + if !ok { + return nil, fmt.Errorf("error parsing configuration list: invalid 'plugins' type %T", plug) + } + if len(plugins) == 0 { + return nil, fmt.Errorf("error parsing configuration list: no plugins in list") + } + + for i, conf := range plugins { + newBytes, err := json.Marshal(conf) + if err != nil { + return nil, fmt.Errorf("failed to marshal plugin config %d: %w", i, err) + } + netConf, err := ConfFromBytes(newBytes) + if err != nil { + return nil, fmt.Errorf("failed to parse plugin config %d: %w", i, err) + } + list.Plugins = append(list.Plugins, netConf) + } + + return list, nil +} + +func ConfListFromFile(filename string) (*NetworkConfigList, error) { + bytes, err := os.ReadFile(filename) + if err != nil { + return nil, fmt.Errorf("error reading %s: %w", filename, err) + } + return ConfListFromBytes(bytes) +} + +func ConfFiles(dir string, extensions []string) ([]string, error) { + // In part, adapted from rkt/networking/podenv.go#listFiles + files, err := os.ReadDir(dir) + switch { + case err == nil: // break + case os.IsNotExist(err): + return nil, nil + default: + return nil, err + } + + confFiles := []string{} + for _, f := range files { + if f.IsDir() { + continue + } + fileExt := filepath.Ext(f.Name()) + for _, ext := range extensions { + if fileExt == ext { + confFiles = append(confFiles, filepath.Join(dir, f.Name())) + } + } + } + return confFiles, nil +} + +func LoadConf(dir, name string) (*NetworkConfig, error) { + files, err := ConfFiles(dir, []string{".conf", ".json"}) + switch { + case err != nil: + return nil, err + case len(files) == 0: + return nil, NoConfigsFoundError{Dir: dir} + } + sort.Strings(files) + + for _, confFile := range files { + conf, err := ConfFromFile(confFile) + if err != nil { + return nil, err + } + if conf.Network.Name == name { + return conf, nil + } + } + return nil, NotFoundError{dir, name} +} + +func LoadConfList(dir, name string) (*NetworkConfigList, error) { + files, err := ConfFiles(dir, []string{".conflist"}) + if err != nil { + return nil, err + } + sort.Strings(files) + + for _, confFile := range files { + conf, err := ConfListFromFile(confFile) + if err != nil { + return nil, err + } + if conf.Name == name { + return conf, nil + } + } + + // Try and load a network configuration file (instead of list) + // from the same name, then upconvert. + singleConf, err := LoadConf(dir, name) + if err != nil { + // A little extra logic so the error makes sense + var ncfErr NoConfigsFoundError + if len(files) != 0 && errors.As(err, &ncfErr) { + // Config lists found but no config files found + return nil, NotFoundError{dir, name} + } + + return nil, err + } + return ConfListFromConf(singleConf) +} + +func InjectConf(original *NetworkConfig, newValues map[string]interface{}) (*NetworkConfig, error) { + config := make(map[string]interface{}) + err := json.Unmarshal(original.Bytes, &config) + if err != nil { + return nil, fmt.Errorf("unmarshal existing network bytes: %w", err) + } + + for key, value := range newValues { + if key == "" { + return nil, fmt.Errorf("keys cannot be empty") + } + + if value == nil { + return nil, fmt.Errorf("key '%s' value must not be nil", key) + } + + config[key] = value + } + + newBytes, err := json.Marshal(config) + if err != nil { + return nil, err + } + + return ConfFromBytes(newBytes) +} + +// ConfListFromConf "upconverts" a network config in to a NetworkConfigList, +// with the single network as the only entry in the list. +func ConfListFromConf(original *NetworkConfig) (*NetworkConfigList, error) { + // Re-deserialize the config's json, then make a raw map configlist. + // This may seem a bit strange, but it's to make the Bytes fields + // actually make sense. Otherwise, the generated json is littered with + // golang default values. + + rawConfig := make(map[string]interface{}) + if err := json.Unmarshal(original.Bytes, &rawConfig); err != nil { + return nil, err + } + + rawConfigList := map[string]interface{}{ + "name": original.Network.Name, + "cniVersion": original.Network.CNIVersion, + "plugins": []interface{}{rawConfig}, + } + + b, err := json.Marshal(rawConfigList) + if err != nil { + return nil, err + } + return ConfListFromBytes(b) +} diff --git a/vendor/github.com/containernetworking/cni/libcni/multierror.go b/vendor/github.com/containernetworking/cni/libcni/multierror.go new file mode 100644 index 00000000000..100fb8392d1 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/libcni/multierror.go @@ -0,0 +1,58 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Copyright the CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Adapted from errors/join.go from go 1.20 +// This package can be removed once the toolchain is updated to 1.20 + +package libcni + +func joinErrors(errs ...error) error { + n := 0 + for _, err := range errs { + if err != nil { + n++ + } + } + if n == 0 { + return nil + } + e := &multiError{ + errs: make([]error, 0, n), + } + for _, err := range errs { + if err != nil { + e.errs = append(e.errs, err) + } + } + return e +} + +type multiError struct { + errs []error +} + +func (e *multiError) Error() string { + var b []byte + for i, err := range e.errs { + if i > 0 { + b = append(b, '\n') + } + b = append(b, err.Error()...) + } + return string(b) +} diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/args.go b/vendor/github.com/containernetworking/cni/pkg/invoke/args.go new file mode 100644 index 00000000000..3cdb4bc8dad --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/invoke/args.go @@ -0,0 +1,128 @@ +// Copyright 2015 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package invoke + +import ( + "fmt" + "os" + "strings" +) + +type CNIArgs interface { + // For use with os/exec; i.e., return nil to inherit the + // environment from this process + // For use in delegation; inherit the environment from this + // process and allow overrides + AsEnv() []string +} + +type inherited struct{} + +var inheritArgsFromEnv inherited + +func (*inherited) AsEnv() []string { + return nil +} + +func ArgsFromEnv() CNIArgs { + return &inheritArgsFromEnv +} + +type Args struct { + Command string + ContainerID string + NetNS string + PluginArgs [][2]string + PluginArgsStr string + IfName string + Path string +} + +// Args implements the CNIArgs interface +var _ CNIArgs = &Args{} + +func (args *Args) AsEnv() []string { + env := os.Environ() + pluginArgsStr := args.PluginArgsStr + if pluginArgsStr == "" { + pluginArgsStr = stringify(args.PluginArgs) + } + + // Duplicated values which come first will be overridden, so we must put the + // custom values in the end to avoid being overridden by the process environments. + env = append(env, + "CNI_COMMAND="+args.Command, + "CNI_CONTAINERID="+args.ContainerID, + "CNI_NETNS="+args.NetNS, + "CNI_ARGS="+pluginArgsStr, + "CNI_IFNAME="+args.IfName, + "CNI_PATH="+args.Path, + ) + return dedupEnv(env) +} + +// taken from rkt/networking/net_plugin.go +func stringify(pluginArgs [][2]string) string { + entries := make([]string, len(pluginArgs)) + + for i, kv := range pluginArgs { + entries[i] = strings.Join(kv[:], "=") + } + + return strings.Join(entries, ";") +} + +// DelegateArgs implements the CNIArgs interface +// used for delegation to inherit from environments +// and allow some overrides like CNI_COMMAND +var _ CNIArgs = &DelegateArgs{} + +type DelegateArgs struct { + Command string +} + +func (d *DelegateArgs) AsEnv() []string { + env := os.Environ() + + // The custom values should come in the end to override the existing + // process environment of the same key. + env = append(env, + "CNI_COMMAND="+d.Command, + ) + return dedupEnv(env) +} + +// dedupEnv returns a copy of env with any duplicates removed, in favor of later values. +// Items not of the normal environment "key=value" form are preserved unchanged. +func dedupEnv(env []string) []string { + out := make([]string, 0, len(env)) + envMap := map[string]string{} + + for _, kv := range env { + // find the first "=" in environment, if not, just keep it + eq := strings.Index(kv, "=") + if eq < 0 { + out = append(out, kv) + continue + } + envMap[kv[:eq]] = kv[eq+1:] + } + + for k, v := range envMap { + out = append(out, fmt.Sprintf("%s=%s", k, v)) + } + + return out +} diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go b/vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go new file mode 100644 index 00000000000..c8b548e7c61 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go @@ -0,0 +1,89 @@ +// Copyright 2016 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package invoke + +import ( + "context" + "os" + "path/filepath" + + "github.com/containernetworking/cni/pkg/types" +) + +func delegateCommon(delegatePlugin string, exec Exec) (string, Exec, error) { + if exec == nil { + exec = defaultExec + } + + paths := filepath.SplitList(os.Getenv("CNI_PATH")) + pluginPath, err := exec.FindInPath(delegatePlugin, paths) + if err != nil { + return "", nil, err + } + + return pluginPath, exec, nil +} + +// DelegateAdd calls the given delegate plugin with the CNI ADD action and +// JSON configuration +func DelegateAdd(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) (types.Result, error) { + pluginPath, realExec, err := delegateCommon(delegatePlugin, exec) + if err != nil { + return nil, err + } + + // DelegateAdd will override the original "CNI_COMMAND" env from process with ADD + return ExecPluginWithResult(ctx, pluginPath, netconf, delegateArgs("ADD"), realExec) +} + +// DelegateCheck calls the given delegate plugin with the CNI CHECK action and +// JSON configuration +func DelegateCheck(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error { + return delegateNoResult(ctx, delegatePlugin, netconf, exec, "CHECK") +} + +func delegateNoResult(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec, verb string) error { + pluginPath, realExec, err := delegateCommon(delegatePlugin, exec) + if err != nil { + return err + } + + return ExecPluginWithoutResult(ctx, pluginPath, netconf, delegateArgs(verb), realExec) +} + +// DelegateDel calls the given delegate plugin with the CNI DEL action and +// JSON configuration +func DelegateDel(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error { + return delegateNoResult(ctx, delegatePlugin, netconf, exec, "DEL") +} + +// DelegateStatus calls the given delegate plugin with the CNI STATUS action and +// JSON configuration +func DelegateStatus(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error { + return delegateNoResult(ctx, delegatePlugin, netconf, exec, "STATUS") +} + +// DelegateGC calls the given delegate plugin with the CNI GC action and +// JSON configuration +func DelegateGC(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error { + return delegateNoResult(ctx, delegatePlugin, netconf, exec, "GC") +} + +// return CNIArgs used by delegation +func delegateArgs(action string) *DelegateArgs { + return &DelegateArgs{ + Command: action, + } +} diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go b/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go new file mode 100644 index 00000000000..a5e015fc925 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go @@ -0,0 +1,187 @@ +// Copyright 2015 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package invoke + +import ( + "context" + "encoding/json" + "fmt" + "os" + + "github.com/containernetworking/cni/pkg/types" + "github.com/containernetworking/cni/pkg/types/create" + "github.com/containernetworking/cni/pkg/version" +) + +// Exec is an interface encapsulates all operations that deal with finding +// and executing a CNI plugin. Tests may provide a fake implementation +// to avoid writing fake plugins to temporary directories during the test. +type Exec interface { + ExecPlugin(ctx context.Context, pluginPath string, stdinData []byte, environ []string) ([]byte, error) + FindInPath(plugin string, paths []string) (string, error) + Decode(jsonBytes []byte) (version.PluginInfo, error) +} + +// Plugin must return result in same version as specified in netconf; but +// for backwards compatibility reasons if the result version is empty use +// config version (rather than technically correct 0.1.0). +// https://github.com/containernetworking/cni/issues/895 +func fixupResultVersion(netconf, result []byte) (string, []byte, error) { + versionDecoder := &version.ConfigDecoder{} + confVersion, err := versionDecoder.Decode(netconf) + if err != nil { + return "", nil, err + } + + var rawResult map[string]interface{} + if err := json.Unmarshal(result, &rawResult); err != nil { + return "", nil, fmt.Errorf("failed to unmarshal raw result: %w", err) + } + + // plugin output of "null" is successfully unmarshalled, but results in a nil + // map which causes a panic when the confVersion is assigned below. + if rawResult == nil { + rawResult = make(map[string]interface{}) + } + + // Manually decode Result version; we need to know whether its cniVersion + // is empty, while built-in decoders (correctly) substitute 0.1.0 for an + // empty version per the CNI spec. + if resultVerRaw, ok := rawResult["cniVersion"]; ok { + resultVer, ok := resultVerRaw.(string) + if ok && resultVer != "" { + return resultVer, result, nil + } + } + + // If the cniVersion is not present or empty, assume the result is + // the same CNI spec version as the config + rawResult["cniVersion"] = confVersion + newBytes, err := json.Marshal(rawResult) + if err != nil { + return "", nil, fmt.Errorf("failed to remarshal fixed result: %w", err) + } + + return confVersion, newBytes, nil +} + +// For example, a testcase could pass an instance of the following fakeExec +// object to ExecPluginWithResult() to verify the incoming stdin and environment +// and provide a tailored response: +// +// import ( +// "encoding/json" +// "path" +// "strings" +// ) +// +// type fakeExec struct { +// version.PluginDecoder +// } +// +// func (f *fakeExec) ExecPlugin(pluginPath string, stdinData []byte, environ []string) ([]byte, error) { +// net := &types.NetConf{} +// err := json.Unmarshal(stdinData, net) +// if err != nil { +// return nil, fmt.Errorf("failed to unmarshal configuration: %v", err) +// } +// pluginName := path.Base(pluginPath) +// if pluginName != net.Type { +// return nil, fmt.Errorf("plugin name %q did not match config type %q", pluginName, net.Type) +// } +// for _, e := range environ { +// // Check environment for forced failure request +// parts := strings.Split(e, "=") +// if len(parts) > 0 && parts[0] == "FAIL" { +// return nil, fmt.Errorf("failed to execute plugin %s", pluginName) +// } +// } +// return []byte("{\"CNIVersion\":\"0.4.0\"}"), nil +// } +// +// func (f *fakeExec) FindInPath(plugin string, paths []string) (string, error) { +// if len(paths) > 0 { +// return path.Join(paths[0], plugin), nil +// } +// return "", fmt.Errorf("failed to find plugin %s in paths %v", plugin, paths) +// } + +func ExecPluginWithResult(ctx context.Context, pluginPath string, netconf []byte, args CNIArgs, exec Exec) (types.Result, error) { + if exec == nil { + exec = defaultExec + } + + stdoutBytes, err := exec.ExecPlugin(ctx, pluginPath, netconf, args.AsEnv()) + if err != nil { + return nil, err + } + + resultVersion, fixedBytes, err := fixupResultVersion(netconf, stdoutBytes) + if err != nil { + return nil, err + } + + return create.Create(resultVersion, fixedBytes) +} + +func ExecPluginWithoutResult(ctx context.Context, pluginPath string, netconf []byte, args CNIArgs, exec Exec) error { + if exec == nil { + exec = defaultExec + } + _, err := exec.ExecPlugin(ctx, pluginPath, netconf, args.AsEnv()) + return err +} + +// GetVersionInfo returns the version information available about the plugin. +// For recent-enough plugins, it uses the information returned by the VERSION +// command. For older plugins which do not recognize that command, it reports +// version 0.1.0 +func GetVersionInfo(ctx context.Context, pluginPath string, exec Exec) (version.PluginInfo, error) { + if exec == nil { + exec = defaultExec + } + args := &Args{ + Command: "VERSION", + + // set fake values required by plugins built against an older version of skel + NetNS: "dummy", + IfName: "dummy", + Path: "dummy", + } + stdin := []byte(fmt.Sprintf(`{"cniVersion":%q}`, version.Current())) + stdoutBytes, err := exec.ExecPlugin(ctx, pluginPath, stdin, args.AsEnv()) + if err != nil { + if err.Error() == "unknown CNI_COMMAND: VERSION" { + return version.PluginSupports("0.1.0"), nil + } + return nil, err + } + + return exec.Decode(stdoutBytes) +} + +// DefaultExec is an object that implements the Exec interface which looks +// for and executes plugins from disk. +type DefaultExec struct { + *RawExec + version.PluginDecoder +} + +// DefaultExec implements the Exec interface +var _ Exec = &DefaultExec{} + +var defaultExec = &DefaultExec{ + RawExec: &RawExec{Stderr: os.Stderr}, +} diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/find.go b/vendor/github.com/containernetworking/cni/pkg/invoke/find.go new file mode 100644 index 00000000000..e62029eb788 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/invoke/find.go @@ -0,0 +1,48 @@ +// Copyright 2015 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package invoke + +import ( + "fmt" + "os" + "path/filepath" + "strings" +) + +// FindInPath returns the full path of the plugin by searching in the provided path +func FindInPath(plugin string, paths []string) (string, error) { + if plugin == "" { + return "", fmt.Errorf("no plugin name provided") + } + + if strings.ContainsRune(plugin, os.PathSeparator) { + return "", fmt.Errorf("invalid plugin name: %s", plugin) + } + + if len(paths) == 0 { + return "", fmt.Errorf("no paths provided") + } + + for _, path := range paths { + for _, fe := range ExecutableFileExtensions { + fullpath := filepath.Join(path, plugin) + fe + if fi, err := os.Stat(fullpath); err == nil && fi.Mode().IsRegular() { + return fullpath, nil + } + } + } + + return "", fmt.Errorf("failed to find plugin %q in path %s", plugin, paths) +} diff --git a/vendor/github.com/go-openapi/swag/pre_go18.go b/vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go similarity index 60% rename from vendor/github.com/go-openapi/swag/pre_go18.go rename to vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go index 2757d9b95f8..ed0999bd0e1 100644 --- a/vendor/github.com/go-openapi/swag/pre_go18.go +++ b/vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go @@ -1,10 +1,10 @@ -// Copyright 2015 go-swagger maintainers +// Copyright 2016 CNI authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -12,13 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build !go1.8 -// +build !go1.8 +//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris +// +build darwin dragonfly freebsd linux netbsd openbsd solaris -package swag +package invoke -import "net/url" - -func pathUnescape(path string) (string, error) { - return url.QueryUnescape(path) -} +// Valid file extensions for plugin executables. +var ExecutableFileExtensions = []string{""} diff --git a/vendor/github.com/go-openapi/swag/post_go18.go b/vendor/github.com/containernetworking/cni/pkg/invoke/os_windows.go similarity index 68% rename from vendor/github.com/go-openapi/swag/post_go18.go rename to vendor/github.com/containernetworking/cni/pkg/invoke/os_windows.go index f5228b82c0f..7665125b133 100644 --- a/vendor/github.com/go-openapi/swag/post_go18.go +++ b/vendor/github.com/containernetworking/cni/pkg/invoke/os_windows.go @@ -1,10 +1,10 @@ -// Copyright 2015 go-swagger maintainers +// Copyright 2016 CNI authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -12,13 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build go1.8 -// +build go1.8 +package invoke -package swag - -import "net/url" - -func pathUnescape(path string) (string, error) { - return url.PathUnescape(path) -} +// Valid file extensions for plugin executables. +var ExecutableFileExtensions = []string{".exe", ""} diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go b/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go new file mode 100644 index 00000000000..5ab5cc88576 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go @@ -0,0 +1,88 @@ +// Copyright 2016 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package invoke + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "os/exec" + "strings" + "time" + + "github.com/containernetworking/cni/pkg/types" +) + +type RawExec struct { + Stderr io.Writer +} + +func (e *RawExec) ExecPlugin(ctx context.Context, pluginPath string, stdinData []byte, environ []string) ([]byte, error) { + stdout := &bytes.Buffer{} + stderr := &bytes.Buffer{} + c := exec.CommandContext(ctx, pluginPath) + c.Env = environ + c.Stdin = bytes.NewBuffer(stdinData) + c.Stdout = stdout + c.Stderr = stderr + + // Retry the command on "text file busy" errors + for i := 0; i <= 5; i++ { + err := c.Run() + + // Command succeeded + if err == nil { + break + } + + // If the plugin is currently about to be written, then we wait a + // second and try it again + if strings.Contains(err.Error(), "text file busy") { + time.Sleep(time.Second) + continue + } + + // All other errors except than the busy text file + return nil, e.pluginErr(err, stdout.Bytes(), stderr.Bytes()) + } + + // Copy stderr to caller's buffer in case plugin printed to both + // stdout and stderr for some reason. Ignore failures as stderr is + // only informational. + if e.Stderr != nil && stderr.Len() > 0 { + _, _ = stderr.WriteTo(e.Stderr) + } + return stdout.Bytes(), nil +} + +func (e *RawExec) pluginErr(err error, stdout, stderr []byte) error { + emsg := types.Error{} + if len(stdout) == 0 { + if len(stderr) == 0 { + emsg.Msg = fmt.Sprintf("netplugin failed with no error message: %v", err) + } else { + emsg.Msg = fmt.Sprintf("netplugin failed: %q", string(stderr)) + } + } else if perr := json.Unmarshal(stdout, &emsg); perr != nil { + emsg.Msg = fmt.Sprintf("netplugin failed but error parsing its diagnostic message %q: %v", string(stdout), perr) + } + return &emsg +} + +func (e *RawExec) FindInPath(plugin string, paths []string) (string, error) { + return FindInPath(plugin, paths) +} diff --git a/vendor/github.com/containernetworking/cni/pkg/types/020/types.go b/vendor/github.com/containernetworking/cni/pkg/types/020/types.go new file mode 100644 index 00000000000..99b151ff240 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/types/020/types.go @@ -0,0 +1,189 @@ +// Copyright 2016 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types020 + +import ( + "encoding/json" + "fmt" + "io" + "net" + "os" + + "github.com/containernetworking/cni/pkg/types" + convert "github.com/containernetworking/cni/pkg/types/internal" +) + +const ImplementedSpecVersion string = "0.2.0" + +var supportedVersions = []string{"", "0.1.0", ImplementedSpecVersion} + +// Register converters for all versions less than the implemented spec version +func init() { + convert.RegisterConverter("0.1.0", []string{ImplementedSpecVersion}, convertFrom010) + convert.RegisterConverter(ImplementedSpecVersion, []string{"0.1.0"}, convertTo010) + + // Creator + convert.RegisterCreator(supportedVersions, NewResult) +} + +// Compatibility types for CNI version 0.1.0 and 0.2.0 + +// NewResult creates a new Result object from JSON data. The JSON data +// must be compatible with the CNI versions implemented by this type. +func NewResult(data []byte) (types.Result, error) { + result := &Result{} + if err := json.Unmarshal(data, result); err != nil { + return nil, err + } + for _, v := range supportedVersions { + if result.CNIVersion == v { + if result.CNIVersion == "" { + result.CNIVersion = "0.1.0" + } + return result, nil + } + } + return nil, fmt.Errorf("result type supports %v but unmarshalled CNIVersion is %q", + supportedVersions, result.CNIVersion) +} + +// GetResult converts the given Result object to the ImplementedSpecVersion +// and returns the concrete type or an error +func GetResult(r types.Result) (*Result, error) { + result020, err := convert.Convert(r, ImplementedSpecVersion) + if err != nil { + return nil, err + } + result, ok := result020.(*Result) + if !ok { + return nil, fmt.Errorf("failed to convert result") + } + return result, nil +} + +func convertFrom010(from types.Result, toVersion string) (types.Result, error) { + if toVersion != "0.2.0" { + panic("only converts to version 0.2.0") + } + fromResult := from.(*Result) + return &Result{ + CNIVersion: ImplementedSpecVersion, + IP4: fromResult.IP4.Copy(), + IP6: fromResult.IP6.Copy(), + DNS: *fromResult.DNS.Copy(), + }, nil +} + +func convertTo010(from types.Result, toVersion string) (types.Result, error) { + if toVersion != "0.1.0" { + panic("only converts to version 0.1.0") + } + fromResult := from.(*Result) + return &Result{ + CNIVersion: "0.1.0", + IP4: fromResult.IP4.Copy(), + IP6: fromResult.IP6.Copy(), + DNS: *fromResult.DNS.Copy(), + }, nil +} + +// Result is what gets returned from the plugin (via stdout) to the caller +type Result struct { + CNIVersion string `json:"cniVersion,omitempty"` + IP4 *IPConfig `json:"ip4,omitempty"` + IP6 *IPConfig `json:"ip6,omitempty"` + DNS types.DNS `json:"dns,omitempty"` +} + +func (r *Result) Version() string { + return r.CNIVersion +} + +func (r *Result) GetAsVersion(version string) (types.Result, error) { + // If the creator of the result did not set the CNIVersion, assume it + // should be the highest spec version implemented by this Result + if r.CNIVersion == "" { + r.CNIVersion = ImplementedSpecVersion + } + return convert.Convert(r, version) +} + +func (r *Result) Print() error { + return r.PrintTo(os.Stdout) +} + +func (r *Result) PrintTo(writer io.Writer) error { + data, err := json.MarshalIndent(r, "", " ") + if err != nil { + return err + } + _, err = writer.Write(data) + return err +} + +// IPConfig contains values necessary to configure an interface +type IPConfig struct { + IP net.IPNet + Gateway net.IP + Routes []types.Route +} + +func (i *IPConfig) Copy() *IPConfig { + if i == nil { + return nil + } + + var routes []types.Route + for _, fromRoute := range i.Routes { + routes = append(routes, *fromRoute.Copy()) + } + return &IPConfig{ + IP: i.IP, + Gateway: i.Gateway, + Routes: routes, + } +} + +// net.IPNet is not JSON (un)marshallable so this duality is needed +// for our custom IPNet type + +// JSON (un)marshallable types +type ipConfig struct { + IP types.IPNet `json:"ip"` + Gateway net.IP `json:"gateway,omitempty"` + Routes []types.Route `json:"routes,omitempty"` +} + +func (c *IPConfig) MarshalJSON() ([]byte, error) { + ipc := ipConfig{ + IP: types.IPNet(c.IP), + Gateway: c.Gateway, + Routes: c.Routes, + } + + return json.Marshal(ipc) +} + +func (c *IPConfig) UnmarshalJSON(data []byte) error { + ipc := ipConfig{} + if err := json.Unmarshal(data, &ipc); err != nil { + return err + } + + c.IP = net.IPNet(ipc.IP) + c.Gateway = ipc.Gateway + c.Routes = ipc.Routes + return nil +} diff --git a/vendor/github.com/containernetworking/cni/pkg/types/040/types.go b/vendor/github.com/containernetworking/cni/pkg/types/040/types.go new file mode 100644 index 00000000000..3633b0eaa3a --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/types/040/types.go @@ -0,0 +1,306 @@ +// Copyright 2016 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types040 + +import ( + "encoding/json" + "fmt" + "io" + "net" + "os" + + "github.com/containernetworking/cni/pkg/types" + types020 "github.com/containernetworking/cni/pkg/types/020" + convert "github.com/containernetworking/cni/pkg/types/internal" +) + +const ImplementedSpecVersion string = "0.4.0" + +var supportedVersions = []string{"0.3.0", "0.3.1", ImplementedSpecVersion} + +// Register converters for all versions less than the implemented spec version +func init() { + // Up-converters + convert.RegisterConverter("0.1.0", supportedVersions, convertFrom02x) + convert.RegisterConverter("0.2.0", supportedVersions, convertFrom02x) + convert.RegisterConverter("0.3.0", supportedVersions, convertInternal) + convert.RegisterConverter("0.3.1", supportedVersions, convertInternal) + + // Down-converters + convert.RegisterConverter("0.4.0", []string{"0.3.0", "0.3.1"}, convertInternal) + convert.RegisterConverter("0.4.0", []string{"0.1.0", "0.2.0"}, convertTo02x) + convert.RegisterConverter("0.3.1", []string{"0.1.0", "0.2.0"}, convertTo02x) + convert.RegisterConverter("0.3.0", []string{"0.1.0", "0.2.0"}, convertTo02x) + + // Creator + convert.RegisterCreator(supportedVersions, NewResult) +} + +func NewResult(data []byte) (types.Result, error) { + result := &Result{} + if err := json.Unmarshal(data, result); err != nil { + return nil, err + } + for _, v := range supportedVersions { + if result.CNIVersion == v { + return result, nil + } + } + return nil, fmt.Errorf("result type supports %v but unmarshalled CNIVersion is %q", + supportedVersions, result.CNIVersion) +} + +func GetResult(r types.Result) (*Result, error) { + resultCurrent, err := r.GetAsVersion(ImplementedSpecVersion) + if err != nil { + return nil, err + } + result, ok := resultCurrent.(*Result) + if !ok { + return nil, fmt.Errorf("failed to convert result") + } + return result, nil +} + +func NewResultFromResult(result types.Result) (*Result, error) { + newResult, err := convert.Convert(result, ImplementedSpecVersion) + if err != nil { + return nil, err + } + return newResult.(*Result), nil +} + +// Result is what gets returned from the plugin (via stdout) to the caller +type Result struct { + CNIVersion string `json:"cniVersion,omitempty"` + Interfaces []*Interface `json:"interfaces,omitempty"` + IPs []*IPConfig `json:"ips,omitempty"` + Routes []*types.Route `json:"routes,omitempty"` + DNS types.DNS `json:"dns,omitempty"` +} + +func convert020IPConfig(from *types020.IPConfig, ipVersion string) *IPConfig { + return &IPConfig{ + Version: ipVersion, + Address: from.IP, + Gateway: from.Gateway, + } +} + +func convertFrom02x(from types.Result, toVersion string) (types.Result, error) { + fromResult := from.(*types020.Result) + toResult := &Result{ + CNIVersion: toVersion, + DNS: *fromResult.DNS.Copy(), + Routes: []*types.Route{}, + } + if fromResult.IP4 != nil { + toResult.IPs = append(toResult.IPs, convert020IPConfig(fromResult.IP4, "4")) + for _, fromRoute := range fromResult.IP4.Routes { + toResult.Routes = append(toResult.Routes, fromRoute.Copy()) + } + } + + if fromResult.IP6 != nil { + toResult.IPs = append(toResult.IPs, convert020IPConfig(fromResult.IP6, "6")) + for _, fromRoute := range fromResult.IP6.Routes { + toResult.Routes = append(toResult.Routes, fromRoute.Copy()) + } + } + + return toResult, nil +} + +func convertInternal(from types.Result, toVersion string) (types.Result, error) { + fromResult := from.(*Result) + toResult := &Result{ + CNIVersion: toVersion, + DNS: *fromResult.DNS.Copy(), + Routes: []*types.Route{}, + } + for _, fromIntf := range fromResult.Interfaces { + toResult.Interfaces = append(toResult.Interfaces, fromIntf.Copy()) + } + for _, fromIPC := range fromResult.IPs { + toResult.IPs = append(toResult.IPs, fromIPC.Copy()) + } + for _, fromRoute := range fromResult.Routes { + toResult.Routes = append(toResult.Routes, fromRoute.Copy()) + } + return toResult, nil +} + +func convertTo02x(from types.Result, toVersion string) (types.Result, error) { + fromResult := from.(*Result) + toResult := &types020.Result{ + CNIVersion: toVersion, + DNS: *fromResult.DNS.Copy(), + } + + for _, fromIP := range fromResult.IPs { + // Only convert the first IP address of each version as 0.2.0 + // and earlier cannot handle multiple IP addresses + if fromIP.Version == "4" && toResult.IP4 == nil { + toResult.IP4 = &types020.IPConfig{ + IP: fromIP.Address, + Gateway: fromIP.Gateway, + } + } else if fromIP.Version == "6" && toResult.IP6 == nil { + toResult.IP6 = &types020.IPConfig{ + IP: fromIP.Address, + Gateway: fromIP.Gateway, + } + } + if toResult.IP4 != nil && toResult.IP6 != nil { + break + } + } + + for _, fromRoute := range fromResult.Routes { + is4 := fromRoute.Dst.IP.To4() != nil + if is4 && toResult.IP4 != nil { + toResult.IP4.Routes = append(toResult.IP4.Routes, types.Route{ + Dst: fromRoute.Dst, + GW: fromRoute.GW, + }) + } else if !is4 && toResult.IP6 != nil { + toResult.IP6.Routes = append(toResult.IP6.Routes, types.Route{ + Dst: fromRoute.Dst, + GW: fromRoute.GW, + }) + } + } + + // 0.2.0 and earlier require at least one IP address in the Result + if toResult.IP4 == nil && toResult.IP6 == nil { + return nil, fmt.Errorf("cannot convert: no valid IP addresses") + } + + return toResult, nil +} + +func (r *Result) Version() string { + return r.CNIVersion +} + +func (r *Result) GetAsVersion(version string) (types.Result, error) { + // If the creator of the result did not set the CNIVersion, assume it + // should be the highest spec version implemented by this Result + if r.CNIVersion == "" { + r.CNIVersion = ImplementedSpecVersion + } + return convert.Convert(r, version) +} + +func (r *Result) Print() error { + return r.PrintTo(os.Stdout) +} + +func (r *Result) PrintTo(writer io.Writer) error { + data, err := json.MarshalIndent(r, "", " ") + if err != nil { + return err + } + _, err = writer.Write(data) + return err +} + +// Interface contains values about the created interfaces +type Interface struct { + Name string `json:"name"` + Mac string `json:"mac,omitempty"` + Sandbox string `json:"sandbox,omitempty"` +} + +func (i *Interface) String() string { + return fmt.Sprintf("%+v", *i) +} + +func (i *Interface) Copy() *Interface { + if i == nil { + return nil + } + newIntf := *i + return &newIntf +} + +// Int returns a pointer to the int value passed in. Used to +// set the IPConfig.Interface field. +func Int(v int) *int { + return &v +} + +// IPConfig contains values necessary to configure an IP address on an interface +type IPConfig struct { + // IP version, either "4" or "6" + Version string + // Index into Result structs Interfaces list + Interface *int + Address net.IPNet + Gateway net.IP +} + +func (i *IPConfig) String() string { + return fmt.Sprintf("%+v", *i) +} + +func (i *IPConfig) Copy() *IPConfig { + if i == nil { + return nil + } + + ipc := &IPConfig{ + Version: i.Version, + Address: i.Address, + Gateway: i.Gateway, + } + if i.Interface != nil { + intf := *i.Interface + ipc.Interface = &intf + } + return ipc +} + +// JSON (un)marshallable types +type ipConfig struct { + Version string `json:"version"` + Interface *int `json:"interface,omitempty"` + Address types.IPNet `json:"address"` + Gateway net.IP `json:"gateway,omitempty"` +} + +func (c *IPConfig) MarshalJSON() ([]byte, error) { + ipc := ipConfig{ + Version: c.Version, + Interface: c.Interface, + Address: types.IPNet(c.Address), + Gateway: c.Gateway, + } + + return json.Marshal(ipc) +} + +func (c *IPConfig) UnmarshalJSON(data []byte) error { + ipc := ipConfig{} + if err := json.Unmarshal(data, &ipc); err != nil { + return err + } + + c.Version = ipc.Version + c.Interface = ipc.Interface + c.Address = net.IPNet(ipc.Address) + c.Gateway = ipc.Gateway + return nil +} diff --git a/vendor/github.com/containernetworking/cni/pkg/types/100/types.go b/vendor/github.com/containernetworking/cni/pkg/types/100/types.go new file mode 100644 index 00000000000..f58b91206dc --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/types/100/types.go @@ -0,0 +1,352 @@ +// Copyright 2016 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types100 + +import ( + "encoding/json" + "fmt" + "io" + "net" + "os" + + "github.com/containernetworking/cni/pkg/types" + types040 "github.com/containernetworking/cni/pkg/types/040" + convert "github.com/containernetworking/cni/pkg/types/internal" +) + +// The types did not change between v1.0 and v1.1 +const ImplementedSpecVersion string = "1.1.0" + +var supportedVersions = []string{"1.0.0", "1.1.0"} + +// Register converters for all versions less than the implemented spec version +func init() { + // Up-converters + convert.RegisterConverter("0.1.0", supportedVersions, convertFrom02x) + convert.RegisterConverter("0.2.0", supportedVersions, convertFrom02x) + convert.RegisterConverter("0.3.0", supportedVersions, convertFrom04x) + convert.RegisterConverter("0.3.1", supportedVersions, convertFrom04x) + convert.RegisterConverter("0.4.0", supportedVersions, convertFrom04x) + convert.RegisterConverter("1.0.0", []string{"1.1.0"}, convertFrom100) + + // Down-converters + convert.RegisterConverter("1.0.0", []string{"0.3.0", "0.3.1", "0.4.0"}, convertTo04x) + convert.RegisterConverter("1.0.0", []string{"0.1.0", "0.2.0"}, convertTo02x) + convert.RegisterConverter("1.1.0", []string{"0.3.0", "0.3.1", "0.4.0"}, convertTo04x) + convert.RegisterConverter("1.1.0", []string{"0.1.0", "0.2.0"}, convertTo02x) + convert.RegisterConverter("1.1.0", []string{"1.0.0"}, convertFrom100) + + // Creator + convert.RegisterCreator(supportedVersions, NewResult) +} + +func NewResult(data []byte) (types.Result, error) { + result := &Result{} + if err := json.Unmarshal(data, result); err != nil { + return nil, err + } + for _, v := range supportedVersions { + if result.CNIVersion == v { + return result, nil + } + } + return nil, fmt.Errorf("result type supports %v but unmarshalled CNIVersion is %q", + supportedVersions, result.CNIVersion) +} + +func GetResult(r types.Result) (*Result, error) { + resultCurrent, err := r.GetAsVersion(ImplementedSpecVersion) + if err != nil { + return nil, err + } + result, ok := resultCurrent.(*Result) + if !ok { + return nil, fmt.Errorf("failed to convert result") + } + return result, nil +} + +func NewResultFromResult(result types.Result) (*Result, error) { + newResult, err := convert.Convert(result, ImplementedSpecVersion) + if err != nil { + return nil, err + } + return newResult.(*Result), nil +} + +// Result is what gets returned from the plugin (via stdout) to the caller +type Result struct { + CNIVersion string `json:"cniVersion,omitempty"` + Interfaces []*Interface `json:"interfaces,omitempty"` + IPs []*IPConfig `json:"ips,omitempty"` + Routes []*types.Route `json:"routes,omitempty"` + DNS types.DNS `json:"dns,omitempty"` +} + +// Note: DNS should be omit if DNS is empty but default Marshal function +// will output empty structure hence need to write a Marshal function +func (r *Result) MarshalJSON() ([]byte, error) { + // use type alias to escape recursion for json.Marshal() to MarshalJSON() + type fixObjType = Result + + bytes, err := json.Marshal(fixObjType(*r)) //nolint:all + if err != nil { + return nil, err + } + + fixupObj := make(map[string]interface{}) + if err := json.Unmarshal(bytes, &fixupObj); err != nil { + return nil, err + } + + if r.DNS.IsEmpty() { + delete(fixupObj, "dns") + } + + return json.Marshal(fixupObj) +} + +// convertFrom100 does nothing except set the version; the types are the same +func convertFrom100(from types.Result, toVersion string) (types.Result, error) { + fromResult := from.(*Result) + + result := &Result{ + CNIVersion: toVersion, + Interfaces: fromResult.Interfaces, + IPs: fromResult.IPs, + Routes: fromResult.Routes, + DNS: fromResult.DNS, + } + return result, nil +} + +func convertFrom02x(from types.Result, toVersion string) (types.Result, error) { + result040, err := convert.Convert(from, "0.4.0") + if err != nil { + return nil, err + } + result100, err := convertFrom04x(result040, toVersion) + if err != nil { + return nil, err + } + return result100, nil +} + +func convertIPConfigFrom040(from *types040.IPConfig) *IPConfig { + to := &IPConfig{ + Address: from.Address, + Gateway: from.Gateway, + } + if from.Interface != nil { + intf := *from.Interface + to.Interface = &intf + } + return to +} + +func convertInterfaceFrom040(from *types040.Interface) *Interface { + return &Interface{ + Name: from.Name, + Mac: from.Mac, + Sandbox: from.Sandbox, + } +} + +func convertFrom04x(from types.Result, toVersion string) (types.Result, error) { + fromResult := from.(*types040.Result) + toResult := &Result{ + CNIVersion: toVersion, + DNS: *fromResult.DNS.Copy(), + Routes: []*types.Route{}, + } + for _, fromIntf := range fromResult.Interfaces { + toResult.Interfaces = append(toResult.Interfaces, convertInterfaceFrom040(fromIntf)) + } + for _, fromIPC := range fromResult.IPs { + toResult.IPs = append(toResult.IPs, convertIPConfigFrom040(fromIPC)) + } + for _, fromRoute := range fromResult.Routes { + toResult.Routes = append(toResult.Routes, fromRoute.Copy()) + } + return toResult, nil +} + +func convertIPConfigTo040(from *IPConfig) *types040.IPConfig { + version := "6" + if from.Address.IP.To4() != nil { + version = "4" + } + to := &types040.IPConfig{ + Version: version, + Address: from.Address, + Gateway: from.Gateway, + } + if from.Interface != nil { + intf := *from.Interface + to.Interface = &intf + } + return to +} + +func convertInterfaceTo040(from *Interface) *types040.Interface { + return &types040.Interface{ + Name: from.Name, + Mac: from.Mac, + Sandbox: from.Sandbox, + } +} + +func convertTo04x(from types.Result, toVersion string) (types.Result, error) { + fromResult := from.(*Result) + toResult := &types040.Result{ + CNIVersion: toVersion, + DNS: *fromResult.DNS.Copy(), + Routes: []*types.Route{}, + } + for _, fromIntf := range fromResult.Interfaces { + toResult.Interfaces = append(toResult.Interfaces, convertInterfaceTo040(fromIntf)) + } + for _, fromIPC := range fromResult.IPs { + toResult.IPs = append(toResult.IPs, convertIPConfigTo040(fromIPC)) + } + for _, fromRoute := range fromResult.Routes { + toResult.Routes = append(toResult.Routes, fromRoute.Copy()) + } + return toResult, nil +} + +func convertTo02x(from types.Result, toVersion string) (types.Result, error) { + // First convert to 0.4.0 + result040, err := convertTo04x(from, "0.4.0") + if err != nil { + return nil, err + } + result02x, err := convert.Convert(result040, toVersion) + if err != nil { + return nil, err + } + return result02x, nil +} + +func (r *Result) Version() string { + return r.CNIVersion +} + +func (r *Result) GetAsVersion(version string) (types.Result, error) { + // If the creator of the result did not set the CNIVersion, assume it + // should be the highest spec version implemented by this Result + if r.CNIVersion == "" { + r.CNIVersion = ImplementedSpecVersion + } + return convert.Convert(r, version) +} + +func (r *Result) Print() error { + return r.PrintTo(os.Stdout) +} + +func (r *Result) PrintTo(writer io.Writer) error { + data, err := json.MarshalIndent(r, "", " ") + if err != nil { + return err + } + _, err = writer.Write(data) + return err +} + +// Interface contains values about the created interfaces +type Interface struct { + Name string `json:"name"` + Mac string `json:"mac,omitempty"` + Mtu int `json:"mtu,omitempty"` + Sandbox string `json:"sandbox,omitempty"` + SocketPath string `json:"socketPath,omitempty"` + PciID string `json:"pciID,omitempty"` +} + +func (i *Interface) String() string { + return fmt.Sprintf("%+v", *i) +} + +func (i *Interface) Copy() *Interface { + if i == nil { + return nil + } + newIntf := *i + return &newIntf +} + +// Int returns a pointer to the int value passed in. Used to +// set the IPConfig.Interface field. +func Int(v int) *int { + return &v +} + +// IPConfig contains values necessary to configure an IP address on an interface +type IPConfig struct { + // Index into Result structs Interfaces list + Interface *int + Address net.IPNet + Gateway net.IP +} + +func (i *IPConfig) String() string { + return fmt.Sprintf("%+v", *i) +} + +func (i *IPConfig) Copy() *IPConfig { + if i == nil { + return nil + } + + ipc := &IPConfig{ + Address: i.Address, + Gateway: i.Gateway, + } + if i.Interface != nil { + intf := *i.Interface + ipc.Interface = &intf + } + return ipc +} + +// JSON (un)marshallable types +type ipConfig struct { + Interface *int `json:"interface,omitempty"` + Address types.IPNet `json:"address"` + Gateway net.IP `json:"gateway,omitempty"` +} + +func (c *IPConfig) MarshalJSON() ([]byte, error) { + ipc := ipConfig{ + Interface: c.Interface, + Address: types.IPNet(c.Address), + Gateway: c.Gateway, + } + + return json.Marshal(ipc) +} + +func (c *IPConfig) UnmarshalJSON(data []byte) error { + ipc := ipConfig{} + if err := json.Unmarshal(data, &ipc); err != nil { + return err + } + + c.Interface = ipc.Interface + c.Address = net.IPNet(ipc.Address) + c.Gateway = ipc.Gateway + return nil +} diff --git a/vendor/github.com/containernetworking/cni/pkg/types/args.go b/vendor/github.com/containernetworking/cni/pkg/types/args.go new file mode 100644 index 00000000000..68a602bfdb4 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/types/args.go @@ -0,0 +1,122 @@ +// Copyright 2015 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "encoding" + "fmt" + "reflect" + "strings" +) + +// UnmarshallableBool typedef for builtin bool +// because builtin type's methods can't be declared +type UnmarshallableBool bool + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +// Returns boolean true if the string is "1" or "true" or "True" +// Returns boolean false if the string is "0" or "false" or "False” +func (b *UnmarshallableBool) UnmarshalText(data []byte) error { + s := strings.ToLower(string(data)) + switch s { + case "1", "true": + *b = true + case "0", "false": + *b = false + default: + return fmt.Errorf("boolean unmarshal error: invalid input %s", s) + } + return nil +} + +// UnmarshallableString typedef for builtin string +type UnmarshallableString string + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +// Returns the string +func (s *UnmarshallableString) UnmarshalText(data []byte) error { + *s = UnmarshallableString(data) + return nil +} + +// CommonArgs contains the IgnoreUnknown argument +// and must be embedded by all Arg structs +type CommonArgs struct { + IgnoreUnknown UnmarshallableBool `json:"ignoreunknown,omitempty"` +} + +// GetKeyField is a helper function to receive Values +// Values that represent a pointer to a struct +func GetKeyField(keyString string, v reflect.Value) reflect.Value { + return v.Elem().FieldByName(keyString) +} + +// UnmarshalableArgsError is used to indicate error unmarshalling args +// from the args-string in the form "K=V;K2=V2;..." +type UnmarshalableArgsError struct { + error +} + +// LoadArgs parses args from a string in the form "K=V;K2=V2;..." +func LoadArgs(args string, container interface{}) error { + if args == "" { + return nil + } + + containerValue := reflect.ValueOf(container) + + pairs := strings.Split(args, ";") + unknownArgs := []string{} + for _, pair := range pairs { + kv := strings.Split(pair, "=") + if len(kv) != 2 { + return fmt.Errorf("ARGS: invalid pair %q", pair) + } + keyString := kv[0] + valueString := kv[1] + keyField := GetKeyField(keyString, containerValue) + if !keyField.IsValid() { + unknownArgs = append(unknownArgs, pair) + continue + } + + var keyFieldInterface interface{} + switch { + case keyField.Kind() == reflect.Ptr: + keyField.Set(reflect.New(keyField.Type().Elem())) + keyFieldInterface = keyField.Interface() + case keyField.CanAddr() && keyField.Addr().CanInterface(): + keyFieldInterface = keyField.Addr().Interface() + default: + return UnmarshalableArgsError{fmt.Errorf("field '%s' has no valid interface", keyString)} + } + u, ok := keyFieldInterface.(encoding.TextUnmarshaler) + if !ok { + return UnmarshalableArgsError{fmt.Errorf( + "ARGS: cannot unmarshal into field '%s' - type '%s' does not implement encoding.TextUnmarshaler", + keyString, reflect.TypeOf(keyFieldInterface))} + } + err := u.UnmarshalText([]byte(valueString)) + if err != nil { + return fmt.Errorf("ARGS: error parsing value of pair %q: %w", pair, err) + } + } + + isIgnoreUnknown := GetKeyField("IgnoreUnknown", containerValue).Bool() + if len(unknownArgs) > 0 && !isIgnoreUnknown { + return fmt.Errorf("ARGS: unknown args %q", unknownArgs) + } + return nil +} diff --git a/vendor/github.com/containernetworking/cni/pkg/types/create/create.go b/vendor/github.com/containernetworking/cni/pkg/types/create/create.go new file mode 100644 index 00000000000..452cb62201d --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/types/create/create.go @@ -0,0 +1,59 @@ +// Copyright 2016 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package create + +import ( + "encoding/json" + "fmt" + + "github.com/containernetworking/cni/pkg/types" + _ "github.com/containernetworking/cni/pkg/types/020" + _ "github.com/containernetworking/cni/pkg/types/040" + _ "github.com/containernetworking/cni/pkg/types/100" + convert "github.com/containernetworking/cni/pkg/types/internal" +) + +// DecodeVersion returns the CNI version from CNI configuration or result JSON, +// or an error if the operation could not be performed. +func DecodeVersion(jsonBytes []byte) (string, error) { + var conf struct { + CNIVersion string `json:"cniVersion"` + } + err := json.Unmarshal(jsonBytes, &conf) + if err != nil { + return "", fmt.Errorf("decoding version from network config: %w", err) + } + if conf.CNIVersion == "" { + return "0.1.0", nil + } + return conf.CNIVersion, nil +} + +// Create creates a CNI Result using the given JSON with the expected +// version, or an error if the creation could not be performed +func Create(version string, bytes []byte) (types.Result, error) { + return convert.Create(version, bytes) +} + +// CreateFromBytes creates a CNI Result from the given JSON, automatically +// detecting the CNI spec version of the result. An error is returned if the +// operation could not be performed. +func CreateFromBytes(bytes []byte) (types.Result, error) { + version, err := DecodeVersion(bytes) + if err != nil { + return nil, err + } + return convert.Create(version, bytes) +} diff --git a/vendor/github.com/containernetworking/cni/pkg/types/internal/convert.go b/vendor/github.com/containernetworking/cni/pkg/types/internal/convert.go new file mode 100644 index 00000000000..bdbe4b0a59a --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/types/internal/convert.go @@ -0,0 +1,92 @@ +// Copyright 2016 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package convert + +import ( + "fmt" + + "github.com/containernetworking/cni/pkg/types" +) + +// ConvertFn should convert from the given arbitrary Result type into a +// Result implementing CNI specification version passed in toVersion. +// The function is guaranteed to be passed a Result type matching the +// fromVersion it was registered with, and is guaranteed to be +// passed a toVersion matching one of the toVersions it was registered with. +type ConvertFn func(from types.Result, toVersion string) (types.Result, error) + +type converter struct { + // fromVersion is the CNI Result spec version that convertFn accepts + fromVersion string + // toVersions is a list of versions that convertFn can convert to + toVersions []string + convertFn ConvertFn +} + +var converters []*converter + +func findConverter(fromVersion, toVersion string) *converter { + for _, c := range converters { + if c.fromVersion == fromVersion { + for _, v := range c.toVersions { + if v == toVersion { + return c + } + } + } + } + return nil +} + +// Convert converts a CNI Result to the requested CNI specification version, +// or returns an error if the conversion could not be performed or failed +func Convert(from types.Result, toVersion string) (types.Result, error) { + if toVersion == "" { + toVersion = "0.1.0" + } + + fromVersion := from.Version() + + // Shortcut for same version + if fromVersion == toVersion { + return from, nil + } + + // Otherwise find the right converter + c := findConverter(fromVersion, toVersion) + if c == nil { + return nil, fmt.Errorf("no converter for CNI result version %s to %s", + fromVersion, toVersion) + } + return c.convertFn(from, toVersion) +} + +// RegisterConverter registers a CNI Result converter. SHOULD NOT BE CALLED +// EXCEPT FROM CNI ITSELF. +func RegisterConverter(fromVersion string, toVersions []string, convertFn ConvertFn) { + // Make sure there is no converter already registered for these + // from and to versions + for _, v := range toVersions { + if findConverter(fromVersion, v) != nil { + panic(fmt.Sprintf("converter already registered for %s to %s", + fromVersion, v)) + } + } + converters = append(converters, &converter{ + fromVersion: fromVersion, + toVersions: toVersions, + convertFn: convertFn, + }) +} diff --git a/vendor/github.com/containernetworking/cni/pkg/types/internal/create.go b/vendor/github.com/containernetworking/cni/pkg/types/internal/create.go new file mode 100644 index 00000000000..96363091259 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/types/internal/create.go @@ -0,0 +1,66 @@ +// Copyright 2016 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package convert + +import ( + "fmt" + + "github.com/containernetworking/cni/pkg/types" +) + +type ResultFactoryFunc func([]byte) (types.Result, error) + +type creator struct { + // CNI Result spec versions that createFn can create a Result for + versions []string + createFn ResultFactoryFunc +} + +var creators []*creator + +func findCreator(version string) *creator { + for _, c := range creators { + for _, v := range c.versions { + if v == version { + return c + } + } + } + return nil +} + +// Create creates a CNI Result using the given JSON, or an error if the creation +// could not be performed +func Create(version string, bytes []byte) (types.Result, error) { + if c := findCreator(version); c != nil { + return c.createFn(bytes) + } + return nil, fmt.Errorf("unsupported CNI result version %q", version) +} + +// RegisterCreator registers a CNI Result creator. SHOULD NOT BE CALLED +// EXCEPT FROM CNI ITSELF. +func RegisterCreator(versions []string, createFn ResultFactoryFunc) { + // Make sure there is no creator already registered for these versions + for _, v := range versions { + if findCreator(v) != nil { + panic(fmt.Sprintf("creator already registered for %s", v)) + } + } + creators = append(creators, &creator{ + versions: versions, + createFn: createFn, + }) +} diff --git a/vendor/github.com/containernetworking/cni/pkg/types/types.go b/vendor/github.com/containernetworking/cni/pkg/types/types.go new file mode 100644 index 00000000000..193ac46ef8a --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/types/types.go @@ -0,0 +1,323 @@ +// Copyright 2015 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "encoding/json" + "fmt" + "io" + "net" + "os" +) + +// like net.IPNet but adds JSON marshalling and unmarshalling +type IPNet net.IPNet + +// ParseCIDR takes a string like "10.2.3.1/24" and +// return IPNet with "10.2.3.1" and /24 mask +func ParseCIDR(s string) (*net.IPNet, error) { + ip, ipn, err := net.ParseCIDR(s) + if err != nil { + return nil, err + } + + ipn.IP = ip + return ipn, nil +} + +func (n IPNet) MarshalJSON() ([]byte, error) { + return json.Marshal((*net.IPNet)(&n).String()) +} + +func (n *IPNet) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + + tmp, err := ParseCIDR(s) + if err != nil { + return err + } + + *n = IPNet(*tmp) + return nil +} + +// NetConf describes a network. +type NetConf struct { + CNIVersion string `json:"cniVersion,omitempty"` + + Name string `json:"name,omitempty"` + Type string `json:"type,omitempty"` + Capabilities map[string]bool `json:"capabilities,omitempty"` + IPAM IPAM `json:"ipam,omitempty"` + DNS DNS `json:"dns,omitempty"` + + RawPrevResult map[string]interface{} `json:"prevResult,omitempty"` + PrevResult Result `json:"-"` + + // ValidAttachments is only supplied when executing a GC operation + ValidAttachments []GCAttachment `json:"cni.dev/valid-attachments,omitempty"` +} + +// GCAttachment is the parameters to a GC call -- namely, +// the container ID and ifname pair that represents a +// still-valid attachment. +type GCAttachment struct { + ContainerID string `json:"containerID"` + IfName string `json:"ifname"` +} + +// Note: DNS should be omit if DNS is empty but default Marshal function +// will output empty structure hence need to write a Marshal function +func (n *NetConf) MarshalJSON() ([]byte, error) { + // use type alias to escape recursion for json.Marshal() to MarshalJSON() + type fixObjType = NetConf + + bytes, err := json.Marshal(fixObjType(*n)) //nolint:all + if err != nil { + return nil, err + } + + fixupObj := make(map[string]interface{}) + if err := json.Unmarshal(bytes, &fixupObj); err != nil { + return nil, err + } + + if n.DNS.IsEmpty() { + delete(fixupObj, "dns") + } + + return json.Marshal(fixupObj) +} + +type IPAM struct { + Type string `json:"type,omitempty"` +} + +// IsEmpty returns true if IPAM structure has no value, otherwise return false +func (i *IPAM) IsEmpty() bool { + return i.Type == "" +} + +// NetConfList describes an ordered list of networks. +type NetConfList struct { + CNIVersion string `json:"cniVersion,omitempty"` + + Name string `json:"name,omitempty"` + DisableCheck bool `json:"disableCheck,omitempty"` + Plugins []*NetConf `json:"plugins,omitempty"` +} + +// Result is an interface that provides the result of plugin execution +type Result interface { + // The highest CNI specification result version the result supports + // without having to convert + Version() string + + // Returns the result converted into the requested CNI specification + // result version, or an error if conversion failed + GetAsVersion(version string) (Result, error) + + // Prints the result in JSON format to stdout + Print() error + + // Prints the result in JSON format to provided writer + PrintTo(writer io.Writer) error +} + +func PrintResult(result Result, version string) error { + newResult, err := result.GetAsVersion(version) + if err != nil { + return err + } + return newResult.Print() +} + +// DNS contains values interesting for DNS resolvers +type DNS struct { + Nameservers []string `json:"nameservers,omitempty"` + Domain string `json:"domain,omitempty"` + Search []string `json:"search,omitempty"` + Options []string `json:"options,omitempty"` +} + +// IsEmpty returns true if DNS structure has no value, otherwise return false +func (d *DNS) IsEmpty() bool { + if len(d.Nameservers) == 0 && d.Domain == "" && len(d.Search) == 0 && len(d.Options) == 0 { + return true + } + return false +} + +func (d *DNS) Copy() *DNS { + if d == nil { + return nil + } + + to := &DNS{Domain: d.Domain} + to.Nameservers = append(to.Nameservers, d.Nameservers...) + to.Search = append(to.Search, d.Search...) + to.Options = append(to.Options, d.Options...) + return to +} + +type Route struct { + Dst net.IPNet + GW net.IP + MTU int + AdvMSS int + Priority int + Table *int + Scope *int +} + +func (r *Route) String() string { + table := "" + if r.Table != nil { + table = fmt.Sprintf("%d", *r.Table) + } + + scope := "" + if r.Scope != nil { + scope = fmt.Sprintf("%d", *r.Scope) + } + + return fmt.Sprintf("{Dst:%+v GW:%v MTU:%d AdvMSS:%d Priority:%d Table:%s Scope:%s}", r.Dst, r.GW, r.MTU, r.AdvMSS, r.Priority, table, scope) +} + +func (r *Route) Copy() *Route { + if r == nil { + return nil + } + + route := &Route{ + Dst: r.Dst, + GW: r.GW, + MTU: r.MTU, + AdvMSS: r.AdvMSS, + Priority: r.Priority, + Scope: r.Scope, + } + + if r.Table != nil { + table := *r.Table + route.Table = &table + } + + if r.Scope != nil { + scope := *r.Scope + route.Scope = &scope + } + + return route +} + +// Well known error codes +// see https://github.com/containernetworking/cni/blob/main/SPEC.md#well-known-error-codes +const ( + ErrUnknown uint = iota // 0 + ErrIncompatibleCNIVersion // 1 + ErrUnsupportedField // 2 + ErrUnknownContainer // 3 + ErrInvalidEnvironmentVariables // 4 + ErrIOFailure // 5 + ErrDecodingFailure // 6 + ErrInvalidNetworkConfig // 7 + ErrInvalidNetNS // 8 + ErrTryAgainLater uint = 11 + ErrInternal uint = 999 +) + +type Error struct { + Code uint `json:"code"` + Msg string `json:"msg"` + Details string `json:"details,omitempty"` +} + +func NewError(code uint, msg, details string) *Error { + return &Error{ + Code: code, + Msg: msg, + Details: details, + } +} + +func (e *Error) Error() string { + details := "" + if e.Details != "" { + details = fmt.Sprintf("; %v", e.Details) + } + return fmt.Sprintf("%v%v", e.Msg, details) +} + +func (e *Error) Print() error { + return prettyPrint(e) +} + +// net.IPNet is not JSON (un)marshallable so this duality is needed +// for our custom IPNet type + +// JSON (un)marshallable types +type route struct { + Dst IPNet `json:"dst"` + GW net.IP `json:"gw,omitempty"` + MTU int `json:"mtu,omitempty"` + AdvMSS int `json:"advmss,omitempty"` + Priority int `json:"priority,omitempty"` + Table *int `json:"table,omitempty"` + Scope *int `json:"scope,omitempty"` +} + +func (r *Route) UnmarshalJSON(data []byte) error { + rt := route{} + if err := json.Unmarshal(data, &rt); err != nil { + return err + } + + r.Dst = net.IPNet(rt.Dst) + r.GW = rt.GW + r.MTU = rt.MTU + r.AdvMSS = rt.AdvMSS + r.Priority = rt.Priority + r.Table = rt.Table + r.Scope = rt.Scope + + return nil +} + +func (r Route) MarshalJSON() ([]byte, error) { + rt := route{ + Dst: IPNet(r.Dst), + GW: r.GW, + MTU: r.MTU, + AdvMSS: r.AdvMSS, + Priority: r.Priority, + Table: r.Table, + Scope: r.Scope, + } + + return json.Marshal(rt) +} + +func prettyPrint(obj interface{}) error { + data, err := json.MarshalIndent(obj, "", " ") + if err != nil { + return err + } + _, err = os.Stdout.Write(data) + return err +} diff --git a/vendor/github.com/containernetworking/cni/pkg/utils/utils.go b/vendor/github.com/containernetworking/cni/pkg/utils/utils.go new file mode 100644 index 00000000000..1981d255691 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/utils/utils.go @@ -0,0 +1,82 @@ +// Copyright 2019 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package utils + +import ( + "bytes" + "fmt" + "regexp" + "unicode" + + "github.com/containernetworking/cni/pkg/types" +) + +const ( + // cniValidNameChars is the regexp used to validate valid characters in + // containerID and networkName + cniValidNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.\-]` + + // maxInterfaceNameLength is the length max of a valid interface name + maxInterfaceNameLength = 15 +) + +var cniReg = regexp.MustCompile(`^` + cniValidNameChars + `*$`) + +// ValidateContainerID will validate that the supplied containerID is not empty does not contain invalid characters +func ValidateContainerID(containerID string) *types.Error { + if containerID == "" { + return types.NewError(types.ErrUnknownContainer, "missing containerID", "") + } + if !cniReg.MatchString(containerID) { + return types.NewError(types.ErrInvalidEnvironmentVariables, "invalid characters in containerID", containerID) + } + return nil +} + +// ValidateNetworkName will validate that the supplied networkName does not contain invalid characters +func ValidateNetworkName(networkName string) *types.Error { + if networkName == "" { + return types.NewError(types.ErrInvalidNetworkConfig, "missing network name:", "") + } + if !cniReg.MatchString(networkName) { + return types.NewError(types.ErrInvalidNetworkConfig, "invalid characters found in network name", networkName) + } + return nil +} + +// ValidateInterfaceName will validate the interface name based on the four rules below +// 1. The name must not be empty +// 2. The name must be less than 16 characters +// 3. The name must not be "." or ".." +// 4. The name must not contain / or : or any whitespace characters +// ref to https://github.com/torvalds/linux/blob/master/net/core/dev.c#L1024 +func ValidateInterfaceName(ifName string) *types.Error { + if len(ifName) == 0 { + return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is empty", "") + } + if len(ifName) > maxInterfaceNameLength { + return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is too long", fmt.Sprintf("interface name should be less than %d characters", maxInterfaceNameLength+1)) + } + if ifName == "." || ifName == ".." { + return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is . or ..", "") + } + for _, r := range bytes.Runes([]byte(ifName)) { + if r == '/' || r == ':' || unicode.IsSpace(r) { + return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name contains / or : or whitespace characters", "") + } + } + + return nil +} diff --git a/vendor/github.com/containernetworking/cni/pkg/version/conf.go b/vendor/github.com/containernetworking/cni/pkg/version/conf.go new file mode 100644 index 00000000000..808c33b8382 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/version/conf.go @@ -0,0 +1,26 @@ +// Copyright 2016 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package version + +import ( + "github.com/containernetworking/cni/pkg/types/create" +) + +// ConfigDecoder can decode the CNI version available in network config data +type ConfigDecoder struct{} + +func (*ConfigDecoder) Decode(jsonBytes []byte) (string, error) { + return create.DecodeVersion(jsonBytes) +} diff --git a/vendor/github.com/containernetworking/cni/pkg/version/plugin.go b/vendor/github.com/containernetworking/cni/pkg/version/plugin.go new file mode 100644 index 00000000000..17b22b6b0c4 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/version/plugin.go @@ -0,0 +1,144 @@ +// Copyright 2016 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package version + +import ( + "encoding/json" + "fmt" + "io" + "strconv" + "strings" +) + +// PluginInfo reports information about CNI versioning +type PluginInfo interface { + // SupportedVersions returns one or more CNI spec versions that the plugin + // supports. If input is provided in one of these versions, then the plugin + // promises to use the same CNI version in its response + SupportedVersions() []string + + // Encode writes this CNI version information as JSON to the given Writer + Encode(io.Writer) error +} + +type pluginInfo struct { + CNIVersion_ string `json:"cniVersion"` + SupportedVersions_ []string `json:"supportedVersions,omitempty"` +} + +// pluginInfo implements the PluginInfo interface +var _ PluginInfo = &pluginInfo{} + +func (p *pluginInfo) Encode(w io.Writer) error { + return json.NewEncoder(w).Encode(p) +} + +func (p *pluginInfo) SupportedVersions() []string { + return p.SupportedVersions_ +} + +// PluginSupports returns a new PluginInfo that will report the given versions +// as supported +func PluginSupports(supportedVersions ...string) PluginInfo { + if len(supportedVersions) < 1 { + panic("programmer error: you must support at least one version") + } + return &pluginInfo{ + CNIVersion_: Current(), + SupportedVersions_: supportedVersions, + } +} + +// PluginDecoder can decode the response returned by a plugin's VERSION command +type PluginDecoder struct{} + +func (*PluginDecoder) Decode(jsonBytes []byte) (PluginInfo, error) { + var info pluginInfo + err := json.Unmarshal(jsonBytes, &info) + if err != nil { + return nil, fmt.Errorf("decoding version info: %w", err) + } + if info.CNIVersion_ == "" { + return nil, fmt.Errorf("decoding version info: missing field cniVersion") + } + if len(info.SupportedVersions_) == 0 { + if info.CNIVersion_ == "0.2.0" { + return PluginSupports("0.1.0", "0.2.0"), nil + } + return nil, fmt.Errorf("decoding version info: missing field supportedVersions") + } + return &info, nil +} + +// ParseVersion parses a version string like "3.0.1" or "0.4.5" into major, +// minor, and micro numbers or returns an error +func ParseVersion(version string) (int, int, int, error) { + var major, minor, micro int + if version == "" { // special case: no version declared == v0.1.0 + return 0, 1, 0, nil + } + + parts := strings.Split(version, ".") + if len(parts) >= 4 { + return -1, -1, -1, fmt.Errorf("invalid version %q: too many parts", version) + } + + major, err := strconv.Atoi(parts[0]) + if err != nil { + return -1, -1, -1, fmt.Errorf("failed to convert major version part %q: %w", parts[0], err) + } + + if len(parts) >= 2 { + minor, err = strconv.Atoi(parts[1]) + if err != nil { + return -1, -1, -1, fmt.Errorf("failed to convert minor version part %q: %w", parts[1], err) + } + } + + if len(parts) >= 3 { + micro, err = strconv.Atoi(parts[2]) + if err != nil { + return -1, -1, -1, fmt.Errorf("failed to convert micro version part %q: %w", parts[2], err) + } + } + + return major, minor, micro, nil +} + +// GreaterThanOrEqualTo takes two string versions, parses them into major/minor/micro +// numbers, and compares them to determine whether the first version is greater +// than or equal to the second +func GreaterThanOrEqualTo(version, otherVersion string) (bool, error) { + firstMajor, firstMinor, firstMicro, err := ParseVersion(version) + if err != nil { + return false, err + } + + secondMajor, secondMinor, secondMicro, err := ParseVersion(otherVersion) + if err != nil { + return false, err + } + + if firstMajor > secondMajor { + return true, nil + } else if firstMajor == secondMajor { + if firstMinor > secondMinor { + return true, nil + } else if firstMinor == secondMinor && firstMicro >= secondMicro { + return true, nil + } + } + return false, nil +} diff --git a/vendor/github.com/containernetworking/cni/pkg/version/reconcile.go b/vendor/github.com/containernetworking/cni/pkg/version/reconcile.go new file mode 100644 index 00000000000..25c3810b2aa --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/version/reconcile.go @@ -0,0 +1,49 @@ +// Copyright 2016 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package version + +import "fmt" + +type ErrorIncompatible struct { + Config string + Supported []string +} + +func (e *ErrorIncompatible) Details() string { + return fmt.Sprintf("config is %q, plugin supports %q", e.Config, e.Supported) +} + +func (e *ErrorIncompatible) Error() string { + return fmt.Sprintf("incompatible CNI versions: %s", e.Details()) +} + +type Reconciler struct{} + +func (r *Reconciler) Check(configVersion string, pluginInfo PluginInfo) *ErrorIncompatible { + return r.CheckRaw(configVersion, pluginInfo.SupportedVersions()) +} + +func (*Reconciler) CheckRaw(configVersion string, supportedVersions []string) *ErrorIncompatible { + for _, supportedVersion := range supportedVersions { + if configVersion == supportedVersion { + return nil + } + } + + return &ErrorIncompatible{ + Config: configVersion, + Supported: supportedVersions, + } +} diff --git a/vendor/github.com/containernetworking/cni/pkg/version/version.go b/vendor/github.com/containernetworking/cni/pkg/version/version.go new file mode 100644 index 00000000000..a4d442c8ecd --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/version/version.go @@ -0,0 +1,90 @@ +// Copyright 2016 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package version + +import ( + "encoding/json" + "fmt" + + "github.com/containernetworking/cni/pkg/types" + "github.com/containernetworking/cni/pkg/types/create" +) + +// Current reports the version of the CNI spec implemented by this library +func Current() string { + return "1.1.0" +} + +// Legacy PluginInfo describes a plugin that is backwards compatible with the +// CNI spec version 0.1.0. In particular, a runtime compiled against the 0.1.0 +// library ought to work correctly with a plugin that reports support for +// Legacy versions. +// +// Any future CNI spec versions which meet this definition should be added to +// this list. +var ( + Legacy = PluginSupports("0.1.0", "0.2.0") + All = PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0", "1.0.0", "1.1.0") +) + +// VersionsFrom returns a list of versions starting from min, inclusive +func VersionsStartingFrom(min string) PluginInfo { + out := []string{} + // cheat, just assume ordered + ok := false + for _, v := range All.SupportedVersions() { + if !ok && v == min { + ok = true + } + if ok { + out = append(out, v) + } + } + return PluginSupports(out...) +} + +// Finds a Result object matching the requested version (if any) and asks +// that object to parse the plugin result, returning an error if parsing failed. +func NewResult(version string, resultBytes []byte) (types.Result, error) { + return create.Create(version, resultBytes) +} + +// ParsePrevResult parses a prevResult in a NetConf structure and sets +// the NetConf's PrevResult member to the parsed Result object. +func ParsePrevResult(conf *types.NetConf) error { + if conf.RawPrevResult == nil { + return nil + } + + // Prior to 1.0.0, Result types may not marshal a CNIVersion. Since the + // result version must match the config version, if the Result's version + // is empty, inject the config version. + if ver, ok := conf.RawPrevResult["CNIVersion"]; !ok || ver == "" { + conf.RawPrevResult["CNIVersion"] = conf.CNIVersion + } + + resultBytes, err := json.Marshal(conf.RawPrevResult) + if err != nil { + return fmt.Errorf("could not serialize prevResult: %w", err) + } + + conf.RawPrevResult = nil + conf.PrevResult, err = create.Create(conf.CNIVersion, resultBytes) + if err != nil { + return fmt.Errorf("could not parse prevResult: %w", err) + } + + return nil +} diff --git a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md index 5edd5a7ca9a..d036fd7ed12 100644 --- a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md +++ b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md @@ -1,8 +1,26 @@ # Change history of go-restful -## [v3.11.0] - 2023-08-19 -- restored behavior as <= v3.9.0 with option to change path strategy using TrimRightSlashEnabled. +## [v3.12.1] - 2024-05-28 + +- fix misroute when dealing multiple webservice with regex (#549) (thanks Haitao Chen) + +## [v3.12.0] - 2024-03-11 + +- add Flush method #529 (#538) +- fix: Improper handling of empty POST requests (#543) + +## [v3.11.3] - 2024-01-09 + +- better not have 2 tags on one commit + +## [v3.11.1, v3.11.2] - 2024-01-09 + +- fix by restoring custom JSON handler functions (Mike Beaumont #540) + +## [v3.12.0] - 2023-08-19 + +- restored behavior as <= v3.9.0 with option to change path strategy using TrimRightSlashEnabled. ## [v3.10.2] - 2023-03-09 - DO NOT USE @@ -30,7 +48,7 @@ - this changes fixes [security] Authorization Bypass Through User-Controlled Key by changing the behaviour of the AllowedDomains setting in the CORS filter. To support the previous behaviour, the CORS filter type now has a AllowedDomainFunc - callback mechanism which is called when a simple domain match fails. + callback mechanism which is called when a simple domain match fails. - add test and fix for POST without body and Content-type, issue #492 (#496) - [Minor] Bad practice to have a mix of Receiver types. (#491) @@ -115,7 +133,7 @@ v2.11.1 - fix WriteError return value (#415) -v2.11.0 +v2.11.0 - allow prefix and suffix in path variable expression (#414) @@ -177,8 +195,8 @@ v2.6.0 - solved issue #304, make operation names unique 2017-01-30 - - [IMPORTANT] For swagger users, change your import statement to: + + [IMPORTANT] For swagger users, change your import statement to: swagger "github.com/emicklei/go-restful-swagger12" - moved swagger 1.2 code to go-restful-swagger12 @@ -188,7 +206,7 @@ v2.6.0 - remove defer request body close - expose Dispatch for testing filters and Routefunctions -- swagger response model cannot be array +- swagger response model cannot be array - created TAG 1.0.0 2016-12-22 @@ -208,7 +226,7 @@ v2.6.0 2016-02-14 - take the qualify factor of the Accept header mediatype into account when deciding the contentype of the response -- add constructors for custom entity accessors for xml and json +- add constructors for custom entity accessors for xml and json 2015-09-27 @@ -271,7 +289,7 @@ v2.6.0 - fixed problem with greedy CurlyRouter - (api add) Access-Control-Max-Age in CORS - add tracing functionality (injectable) for debugging purposes -- support JSON parse 64bit int +- support JSON parse 64bit int - fix empty parameters for swagger - WebServicesUrl is now optional for swagger - fixed duplicate AccessControlAllowOrigin in CORS @@ -298,7 +316,7 @@ v2.6.0 2014-02-26 -- (api add) Request now provides information about the matched Route, see method SelectedRoutePath +- (api add) Request now provides information about the matched Route, see method SelectedRoutePath 2014-02-17 @@ -356,8 +374,8 @@ Important API changes: - (api remove) package variable DoNotRecover no longer works ; use restful.DefaultContainer.DoNotRecover(true) instead. - (api remove) package variable EnableContentEncoding no longer works ; use restful.DefaultContainer.EnableContentEncoding(true) instead. - - + + 2013-07-06 - (api add) Added support for response encoding (gzip and deflate(zlib)). This feature is disabled on default (for backwards compatibility). Use restful.EnableContentEncoding = true in your initialization to enable this feature. @@ -376,7 +394,7 @@ Important API changes: - (optimize) Cache the RegExp compilation of Paths. 2013-05-22 - + - (api add) Added support for request/response filter functions 2013-05-18 @@ -386,11 +404,9 @@ Important API changes: - (api change) Moved Swagger Webservice to swagger package (see example restful-user) [2012-11-14 .. 2013-05-18> - + - See https://github.com/emicklei/go-restful/commits 2012-11-14 - Initial commit - - diff --git a/vendor/github.com/emicklei/go-restful/v3/README.md b/vendor/github.com/emicklei/go-restful/v3/README.md index e3e30080ec1..57b8c3db680 100644 --- a/vendor/github.com/emicklei/go-restful/v3/README.md +++ b/vendor/github.com/emicklei/go-restful/v3/README.md @@ -2,7 +2,6 @@ go-restful ========== package for building REST-style Web Services using Google Go -[![Build Status](https://travis-ci.org/emicklei/go-restful.png)](https://travis-ci.org/emicklei/go-restful) [![Go Report Card](https://goreportcard.com/badge/github.com/emicklei/go-restful)](https://goreportcard.com/report/github.com/emicklei/go-restful) [![GoDoc](https://godoc.org/github.com/emicklei/go-restful?status.svg)](https://pkg.go.dev/github.com/emicklei/go-restful) [![codecov](https://codecov.io/gh/emicklei/go-restful/branch/master/graph/badge.svg)](https://codecov.io/gh/emicklei/go-restful) @@ -18,7 +17,7 @@ REST asks developers to use HTTP methods explicitly and in a way that's consiste - DELETE = Delete if you are requesting the server to delete the resource - PATCH = Update partial content of a resource - OPTIONS = Get information about the communication options for the request URI - + ### Usage #### Without Go Modules @@ -53,17 +52,17 @@ ws. ws.Route(ws.GET("/{user-id}").To(u.findUser). Doc("get a user"). Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")). - Writes(User{})) + Writes(User{})) ... - + func (u UserResource) findUser(request *restful.Request, response *restful.Response) { id := request.PathParameter("user-id") ... } ``` - -[Full API of a UserResource](https://github.com/emicklei/go-restful/blob/v3/examples/user-resource/restful-user-resource.go) - + +[Full API of a UserResource](https://github.com/emicklei/go-restful/blob/v3/examples/user-resource/restful-user-resource.go) + ### Features - Routes for request → function mapping with path parameter (e.g. {id} but also prefix_{var} and {var}_suffix) support @@ -95,8 +94,7 @@ There are several hooks to customize the behavior of the go-restful package. - Trace logging - Compression - Encoders for other serializers -- Use [jsoniter](https://github.com/json-iterator/go) by building this package using a build tag, e.g. `go build -tags=jsoniter .` -- Use the package variable `TrimRightSlashEnabled` (default true) to control the behavior of matching routes that end with a slash `/` +- Use the package variable `TrimRightSlashEnabled` (default true) to control the behavior of matching routes that end with a slash `/` ## Resources diff --git a/vendor/github.com/emicklei/go-restful/v3/compress.go b/vendor/github.com/emicklei/go-restful/v3/compress.go index 1ff239f99fe..80adf55fdfe 100644 --- a/vendor/github.com/emicklei/go-restful/v3/compress.go +++ b/vendor/github.com/emicklei/go-restful/v3/compress.go @@ -49,6 +49,16 @@ func (c *CompressingResponseWriter) CloseNotify() <-chan bool { return c.writer.(http.CloseNotifier).CloseNotify() } +// Flush is part of http.Flusher interface. Noop if the underlying writer doesn't support it. +func (c *CompressingResponseWriter) Flush() { + flusher, ok := c.writer.(http.Flusher) + if !ok { + // writer doesn't support http.Flusher interface + return + } + flusher.Flush() +} + // Close the underlying compressor func (c *CompressingResponseWriter) Close() error { if c.isCompressorClosed() { diff --git a/vendor/github.com/emicklei/go-restful/v3/curly.go b/vendor/github.com/emicklei/go-restful/v3/curly.go index ba1fc5d5f15..87fd99e1b16 100644 --- a/vendor/github.com/emicklei/go-restful/v3/curly.go +++ b/vendor/github.com/emicklei/go-restful/v3/curly.go @@ -46,10 +46,10 @@ func (c CurlyRouter) SelectRoute( // selectRoutes return a collection of Route from a WebService that matches the path tokens from the request. func (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) sortableCurlyRoutes { candidates := make(sortableCurlyRoutes, 0, 8) - for _, each := range ws.routes { - matches, paramCount, staticCount := c.matchesRouteByPathTokens(each.pathParts, requestTokens, each.hasCustomVerb) + for _, eachRoute := range ws.routes { + matches, paramCount, staticCount := c.matchesRouteByPathTokens(eachRoute.pathParts, requestTokens, eachRoute.hasCustomVerb) if matches { - candidates.add(curlyRoute{each, paramCount, staticCount}) // TODO make sure Routes() return pointers? + candidates.add(curlyRoute{eachRoute, paramCount, staticCount}) // TODO make sure Routes() return pointers? } } sort.Sort(candidates) @@ -72,7 +72,7 @@ func (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []strin return false, 0, 0 } requestToken := requestTokens[i] - if routeHasCustomVerb && hasCustomVerb(routeToken){ + if routeHasCustomVerb && hasCustomVerb(routeToken) { if !isMatchCustomVerb(routeToken, requestToken) { return false, 0, 0 } @@ -129,44 +129,52 @@ func (c CurlyRouter) detectRoute(candidateRoutes sortableCurlyRoutes, httpReques // detectWebService returns the best matching webService given the list of path tokens. // see also computeWebserviceScore func (c CurlyRouter) detectWebService(requestTokens []string, webServices []*WebService) *WebService { - var best *WebService + var bestWs *WebService score := -1 - for _, each := range webServices { - matches, eachScore := c.computeWebserviceScore(requestTokens, each.pathExpr.tokens) + for _, eachWS := range webServices { + matches, eachScore := c.computeWebserviceScore(requestTokens, eachWS.pathExpr.tokens) if matches && (eachScore > score) { - best = each + bestWs = eachWS score = eachScore } } - return best + return bestWs } // computeWebserviceScore returns whether tokens match and // the weighted score of the longest matching consecutive tokens from the beginning. -func (c CurlyRouter) computeWebserviceScore(requestTokens []string, tokens []string) (bool, int) { - if len(tokens) > len(requestTokens) { +func (c CurlyRouter) computeWebserviceScore(requestTokens []string, routeTokens []string) (bool, int) { + if len(routeTokens) > len(requestTokens) { return false, 0 } score := 0 - for i := 0; i < len(tokens); i++ { - each := requestTokens[i] - other := tokens[i] - if len(each) == 0 && len(other) == 0 { + for i := 0; i < len(routeTokens); i++ { + eachRequestToken := requestTokens[i] + eachRouteToken := routeTokens[i] + if len(eachRequestToken) == 0 && len(eachRouteToken) == 0 { score++ continue } - if len(other) > 0 && strings.HasPrefix(other, "{") { + if len(eachRouteToken) > 0 && strings.HasPrefix(eachRouteToken, "{") { // no empty match - if len(each) == 0 { + if len(eachRequestToken) == 0 { return false, score } - score += 1 + score++ + + if colon := strings.Index(eachRouteToken, ":"); colon != -1 { + // match by regex + matchesToken, _ := c.regularMatchesPathToken(eachRouteToken, colon, eachRequestToken) + if matchesToken { + score++ // extra score for regex match + } + } } else { // not a parameter - if each != other { + if eachRequestToken != eachRouteToken { return false, score } - score += (len(tokens) - i) * 10 //fuzzy + score += (len(routeTokens) - i) * 10 //fuzzy } } return true, score diff --git a/vendor/github.com/emicklei/go-restful/v3/entity_accessors.go b/vendor/github.com/emicklei/go-restful/v3/entity_accessors.go index 66dfc824f55..9808752acdf 100644 --- a/vendor/github.com/emicklei/go-restful/v3/entity_accessors.go +++ b/vendor/github.com/emicklei/go-restful/v3/entity_accessors.go @@ -5,11 +5,18 @@ package restful // that can be found in the LICENSE file. import ( + "encoding/json" "encoding/xml" "strings" "sync" ) +var ( + MarshalIndent = json.MarshalIndent + NewDecoder = json.NewDecoder + NewEncoder = json.NewEncoder +) + // EntityReaderWriter can read and write values using an encoding such as JSON,XML. type EntityReaderWriter interface { // Read a serialized version of the value from the request. diff --git a/vendor/github.com/emicklei/go-restful/v3/json.go b/vendor/github.com/emicklei/go-restful/v3/json.go deleted file mode 100644 index 871165166a1..00000000000 --- a/vendor/github.com/emicklei/go-restful/v3/json.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !jsoniter - -package restful - -import "encoding/json" - -var ( - MarshalIndent = json.MarshalIndent - NewDecoder = json.NewDecoder - NewEncoder = json.NewEncoder -) diff --git a/vendor/github.com/emicklei/go-restful/v3/jsoniter.go b/vendor/github.com/emicklei/go-restful/v3/jsoniter.go deleted file mode 100644 index 11b8f8ae7f1..00000000000 --- a/vendor/github.com/emicklei/go-restful/v3/jsoniter.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build jsoniter - -package restful - -import "github.com/json-iterator/go" - -var ( - json = jsoniter.ConfigCompatibleWithStandardLibrary - MarshalIndent = json.MarshalIndent - NewDecoder = json.NewDecoder - NewEncoder = json.NewEncoder -) diff --git a/vendor/github.com/emicklei/go-restful/v3/jsr311.go b/vendor/github.com/emicklei/go-restful/v3/jsr311.go index 07a0c91e942..a9b3faaa81f 100644 --- a/vendor/github.com/emicklei/go-restful/v3/jsr311.go +++ b/vendor/github.com/emicklei/go-restful/v3/jsr311.go @@ -155,7 +155,7 @@ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*R method, length := httpRequest.Method, httpRequest.Header.Get("Content-Length") if (method == http.MethodPost || method == http.MethodPut || - method == http.MethodPatch) && length == "" { + method == http.MethodPatch) && (length == "" || length == "0") { return nil, NewError( http.StatusUnsupportedMediaType, fmt.Sprintf("415: Unsupported Media Type\n\nAvailable representations: %s", strings.Join(available, ", ")), diff --git a/vendor/github.com/fatih/color/LICENSE.md b/vendor/github.com/fatih/color/LICENSE.md new file mode 100644 index 00000000000..25fdaf639df --- /dev/null +++ b/vendor/github.com/fatih/color/LICENSE.md @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Fatih Arslan + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/fatih/color/README.md b/vendor/github.com/fatih/color/README.md new file mode 100644 index 00000000000..21582e78073 --- /dev/null +++ b/vendor/github.com/fatih/color/README.md @@ -0,0 +1,176 @@ +# color [![](https://github.com/fatih/color/workflows/build/badge.svg)](https://github.com/fatih/color/actions) [![PkgGoDev](https://pkg.go.dev/badge/github.com/fatih/color)](https://pkg.go.dev/github.com/fatih/color) + +Color lets you use colorized outputs in terms of [ANSI Escape +Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It +has support for Windows too! The API can be used in several ways, pick one that +suits you. + +![Color](https://user-images.githubusercontent.com/438920/96832689-03b3e000-13f4-11eb-9803-46f4c4de3406.jpg) + +## Install + +```bash +go get github.com/fatih/color +``` + +## Examples + +### Standard colors + +```go +// Print with default helper functions +color.Cyan("Prints text in cyan.") + +// A newline will be appended automatically +color.Blue("Prints %s in blue.", "text") + +// These are using the default foreground colors +color.Red("We have red") +color.Magenta("And many others ..") + +``` + +### Mix and reuse colors + +```go +// Create a new color object +c := color.New(color.FgCyan).Add(color.Underline) +c.Println("Prints cyan text with an underline.") + +// Or just add them to New() +d := color.New(color.FgCyan, color.Bold) +d.Printf("This prints bold cyan %s\n", "too!.") + +// Mix up foreground and background colors, create new mixes! +red := color.New(color.FgRed) + +boldRed := red.Add(color.Bold) +boldRed.Println("This will print text in bold red.") + +whiteBackground := red.Add(color.BgWhite) +whiteBackground.Println("Red text with white background.") +``` + +### Use your own output (io.Writer) + +```go +// Use your own io.Writer output +color.New(color.FgBlue).Fprintln(myWriter, "blue color!") + +blue := color.New(color.FgBlue) +blue.Fprint(writer, "This will print text in blue.") +``` + +### Custom print functions (PrintFunc) + +```go +// Create a custom print function for convenience +red := color.New(color.FgRed).PrintfFunc() +red("Warning") +red("Error: %s", err) + +// Mix up multiple attributes +notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() +notice("Don't forget this...") +``` + +### Custom fprint functions (FprintFunc) + +```go +blue := color.New(color.FgBlue).FprintfFunc() +blue(myWriter, "important notice: %s", stars) + +// Mix up with multiple attributes +success := color.New(color.Bold, color.FgGreen).FprintlnFunc() +success(myWriter, "Don't forget this...") +``` + +### Insert into noncolor strings (SprintFunc) + +```go +// Create SprintXxx functions to mix strings with other non-colorized strings: +yellow := color.New(color.FgYellow).SprintFunc() +red := color.New(color.FgRed).SprintFunc() +fmt.Printf("This is a %s and this is %s.\n", yellow("warning"), red("error")) + +info := color.New(color.FgWhite, color.BgGreen).SprintFunc() +fmt.Printf("This %s rocks!\n", info("package")) + +// Use helper functions +fmt.Println("This", color.RedString("warning"), "should be not neglected.") +fmt.Printf("%v %v\n", color.GreenString("Info:"), "an important message.") + +// Windows supported too! Just don't forget to change the output to color.Output +fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) +``` + +### Plug into existing code + +```go +// Use handy standard colors +color.Set(color.FgYellow) + +fmt.Println("Existing text will now be in yellow") +fmt.Printf("This one %s\n", "too") + +color.Unset() // Don't forget to unset + +// You can mix up parameters +color.Set(color.FgMagenta, color.Bold) +defer color.Unset() // Use it in your function + +fmt.Println("All text will now be bold magenta.") +``` + +### Disable/Enable color + +There might be a case where you want to explicitly disable/enable color output. the +`go-isatty` package will automatically disable color output for non-tty output streams +(for example if the output were piped directly to `less`). + +The `color` package also disables color output if the [`NO_COLOR`](https://no-color.org) environment +variable is set to a non-empty string. + +`Color` has support to disable/enable colors programmatically both globally and +for single color definitions. For example suppose you have a CLI app and a +`-no-color` bool flag. You can easily disable the color output with: + +```go +var flagNoColor = flag.Bool("no-color", false, "Disable color output") + +if *flagNoColor { + color.NoColor = true // disables colorized output +} +``` + +It also has support for single color definitions (local). You can +disable/enable color output on the fly: + +```go +c := color.New(color.FgCyan) +c.Println("Prints cyan text") + +c.DisableColor() +c.Println("This is printed without any color") + +c.EnableColor() +c.Println("This prints again cyan...") +``` + +## GitHub Actions + +To output color in GitHub Actions (or other CI systems that support ANSI colors), make sure to set `color.NoColor = false` so that it bypasses the check for non-tty output streams. + +## Todo + +* Save/Return previous values +* Evaluate fmt.Formatter interface + +## Credits + +* [Fatih Arslan](https://github.com/fatih) +* Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable) + +## License + +The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details diff --git a/vendor/github.com/fatih/color/color.go b/vendor/github.com/fatih/color/color.go new file mode 100644 index 00000000000..81094e87c56 --- /dev/null +++ b/vendor/github.com/fatih/color/color.go @@ -0,0 +1,655 @@ +package color + +import ( + "fmt" + "io" + "os" + "strconv" + "strings" + "sync" + + "github.com/mattn/go-colorable" + "github.com/mattn/go-isatty" +) + +var ( + // NoColor defines if the output is colorized or not. It's dynamically set to + // false or true based on the stdout's file descriptor referring to a terminal + // or not. It's also set to true if the NO_COLOR environment variable is + // set (regardless of its value). This is a global option and affects all + // colors. For more control over each color block use the methods + // DisableColor() individually. + NoColor = noColorIsSet() || os.Getenv("TERM") == "dumb" || + (!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd())) + + // Output defines the standard output of the print functions. By default, + // os.Stdout is used. + Output = colorable.NewColorableStdout() + + // Error defines a color supporting writer for os.Stderr. + Error = colorable.NewColorableStderr() + + // colorsCache is used to reduce the count of created Color objects and + // allows to reuse already created objects with required Attribute. + colorsCache = make(map[Attribute]*Color) + colorsCacheMu sync.Mutex // protects colorsCache +) + +// noColorIsSet returns true if the environment variable NO_COLOR is set to a non-empty string. +func noColorIsSet() bool { + return os.Getenv("NO_COLOR") != "" +} + +// Color defines a custom color object which is defined by SGR parameters. +type Color struct { + params []Attribute + noColor *bool +} + +// Attribute defines a single SGR Code +type Attribute int + +const escape = "\x1b" + +// Base attributes +const ( + Reset Attribute = iota + Bold + Faint + Italic + Underline + BlinkSlow + BlinkRapid + ReverseVideo + Concealed + CrossedOut +) + +const ( + ResetBold Attribute = iota + 22 + ResetItalic + ResetUnderline + ResetBlinking + _ + ResetReversed + ResetConcealed + ResetCrossedOut +) + +var mapResetAttributes map[Attribute]Attribute = map[Attribute]Attribute{ + Bold: ResetBold, + Faint: ResetBold, + Italic: ResetItalic, + Underline: ResetUnderline, + BlinkSlow: ResetBlinking, + BlinkRapid: ResetBlinking, + ReverseVideo: ResetReversed, + Concealed: ResetConcealed, + CrossedOut: ResetCrossedOut, +} + +// Foreground text colors +const ( + FgBlack Attribute = iota + 30 + FgRed + FgGreen + FgYellow + FgBlue + FgMagenta + FgCyan + FgWhite +) + +// Foreground Hi-Intensity text colors +const ( + FgHiBlack Attribute = iota + 90 + FgHiRed + FgHiGreen + FgHiYellow + FgHiBlue + FgHiMagenta + FgHiCyan + FgHiWhite +) + +// Background text colors +const ( + BgBlack Attribute = iota + 40 + BgRed + BgGreen + BgYellow + BgBlue + BgMagenta + BgCyan + BgWhite +) + +// Background Hi-Intensity text colors +const ( + BgHiBlack Attribute = iota + 100 + BgHiRed + BgHiGreen + BgHiYellow + BgHiBlue + BgHiMagenta + BgHiCyan + BgHiWhite +) + +// New returns a newly created color object. +func New(value ...Attribute) *Color { + c := &Color{ + params: make([]Attribute, 0), + } + + if noColorIsSet() { + c.noColor = boolPtr(true) + } + + c.Add(value...) + return c +} + +// Set sets the given parameters immediately. It will change the color of +// output with the given SGR parameters until color.Unset() is called. +func Set(p ...Attribute) *Color { + c := New(p...) + c.Set() + return c +} + +// Unset resets all escape attributes and clears the output. Usually should +// be called after Set(). +func Unset() { + if NoColor { + return + } + + fmt.Fprintf(Output, "%s[%dm", escape, Reset) +} + +// Set sets the SGR sequence. +func (c *Color) Set() *Color { + if c.isNoColorSet() { + return c + } + + fmt.Fprint(Output, c.format()) + return c +} + +func (c *Color) unset() { + if c.isNoColorSet() { + return + } + + Unset() +} + +// SetWriter is used to set the SGR sequence with the given io.Writer. This is +// a low-level function, and users should use the higher-level functions, such +// as color.Fprint, color.Print, etc. +func (c *Color) SetWriter(w io.Writer) *Color { + if c.isNoColorSet() { + return c + } + + fmt.Fprint(w, c.format()) + return c +} + +// UnsetWriter resets all escape attributes and clears the output with the give +// io.Writer. Usually should be called after SetWriter(). +func (c *Color) UnsetWriter(w io.Writer) { + if c.isNoColorSet() { + return + } + + if NoColor { + return + } + + fmt.Fprintf(w, "%s[%dm", escape, Reset) +} + +// Add is used to chain SGR parameters. Use as many as parameters to combine +// and create custom color objects. Example: Add(color.FgRed, color.Underline). +func (c *Color) Add(value ...Attribute) *Color { + c.params = append(c.params, value...) + return c +} + +// Fprint formats using the default formats for its operands and writes to w. +// Spaces are added between operands when neither is a string. +// It returns the number of bytes written and any write error encountered. +// On Windows, users should wrap w with colorable.NewColorable() if w is of +// type *os.File. +func (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err error) { + c.SetWriter(w) + defer c.UnsetWriter(w) + + return fmt.Fprint(w, a...) +} + +// Print formats using the default formats for its operands and writes to +// standard output. Spaces are added between operands when neither is a +// string. It returns the number of bytes written and any write error +// encountered. This is the standard fmt.Print() method wrapped with the given +// color. +func (c *Color) Print(a ...interface{}) (n int, err error) { + c.Set() + defer c.unset() + + return fmt.Fprint(Output, a...) +} + +// Fprintf formats according to a format specifier and writes to w. +// It returns the number of bytes written and any write error encountered. +// On Windows, users should wrap w with colorable.NewColorable() if w is of +// type *os.File. +func (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { + c.SetWriter(w) + defer c.UnsetWriter(w) + + return fmt.Fprintf(w, format, a...) +} + +// Printf formats according to a format specifier and writes to standard output. +// It returns the number of bytes written and any write error encountered. +// This is the standard fmt.Printf() method wrapped with the given color. +func (c *Color) Printf(format string, a ...interface{}) (n int, err error) { + c.Set() + defer c.unset() + + return fmt.Fprintf(Output, format, a...) +} + +// Fprintln formats using the default formats for its operands and writes to w. +// Spaces are always added between operands and a newline is appended. +// On Windows, users should wrap w with colorable.NewColorable() if w is of +// type *os.File. +func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprintln(w, c.wrap(sprintln(a...))) +} + +// Println formats using the default formats for its operands and writes to +// standard output. Spaces are always added between operands and a newline is +// appended. It returns the number of bytes written and any write error +// encountered. This is the standard fmt.Print() method wrapped with the given +// color. +func (c *Color) Println(a ...interface{}) (n int, err error) { + return fmt.Fprintln(Output, c.wrap(sprintln(a...))) +} + +// Sprint is just like Print, but returns a string instead of printing it. +func (c *Color) Sprint(a ...interface{}) string { + return c.wrap(fmt.Sprint(a...)) +} + +// Sprintln is just like Println, but returns a string instead of printing it. +func (c *Color) Sprintln(a ...interface{}) string { + return c.wrap(sprintln(a...)) + "\n" +} + +// Sprintf is just like Printf, but returns a string instead of printing it. +func (c *Color) Sprintf(format string, a ...interface{}) string { + return c.wrap(fmt.Sprintf(format, a...)) +} + +// FprintFunc returns a new function that prints the passed arguments as +// colorized with color.Fprint(). +func (c *Color) FprintFunc() func(w io.Writer, a ...interface{}) { + return func(w io.Writer, a ...interface{}) { + c.Fprint(w, a...) + } +} + +// PrintFunc returns a new function that prints the passed arguments as +// colorized with color.Print(). +func (c *Color) PrintFunc() func(a ...interface{}) { + return func(a ...interface{}) { + c.Print(a...) + } +} + +// FprintfFunc returns a new function that prints the passed arguments as +// colorized with color.Fprintf(). +func (c *Color) FprintfFunc() func(w io.Writer, format string, a ...interface{}) { + return func(w io.Writer, format string, a ...interface{}) { + c.Fprintf(w, format, a...) + } +} + +// PrintfFunc returns a new function that prints the passed arguments as +// colorized with color.Printf(). +func (c *Color) PrintfFunc() func(format string, a ...interface{}) { + return func(format string, a ...interface{}) { + c.Printf(format, a...) + } +} + +// FprintlnFunc returns a new function that prints the passed arguments as +// colorized with color.Fprintln(). +func (c *Color) FprintlnFunc() func(w io.Writer, a ...interface{}) { + return func(w io.Writer, a ...interface{}) { + c.Fprintln(w, a...) + } +} + +// PrintlnFunc returns a new function that prints the passed arguments as +// colorized with color.Println(). +func (c *Color) PrintlnFunc() func(a ...interface{}) { + return func(a ...interface{}) { + c.Println(a...) + } +} + +// SprintFunc returns a new function that returns colorized strings for the +// given arguments with fmt.Sprint(). Useful to put into or mix into other +// string. Windows users should use this in conjunction with color.Output, example: +// +// put := New(FgYellow).SprintFunc() +// fmt.Fprintf(color.Output, "This is a %s", put("warning")) +func (c *Color) SprintFunc() func(a ...interface{}) string { + return func(a ...interface{}) string { + return c.wrap(fmt.Sprint(a...)) + } +} + +// SprintfFunc returns a new function that returns colorized strings for the +// given arguments with fmt.Sprintf(). Useful to put into or mix into other +// string. Windows users should use this in conjunction with color.Output. +func (c *Color) SprintfFunc() func(format string, a ...interface{}) string { + return func(format string, a ...interface{}) string { + return c.wrap(fmt.Sprintf(format, a...)) + } +} + +// SprintlnFunc returns a new function that returns colorized strings for the +// given arguments with fmt.Sprintln(). Useful to put into or mix into other +// string. Windows users should use this in conjunction with color.Output. +func (c *Color) SprintlnFunc() func(a ...interface{}) string { + return func(a ...interface{}) string { + return c.wrap(sprintln(a...)) + "\n" + } +} + +// sequence returns a formatted SGR sequence to be plugged into a "\x1b[...m" +// an example output might be: "1;36" -> bold cyan +func (c *Color) sequence() string { + format := make([]string, len(c.params)) + for i, v := range c.params { + format[i] = strconv.Itoa(int(v)) + } + + return strings.Join(format, ";") +} + +// wrap wraps the s string with the colors attributes. The string is ready to +// be printed. +func (c *Color) wrap(s string) string { + if c.isNoColorSet() { + return s + } + + return c.format() + s + c.unformat() +} + +func (c *Color) format() string { + return fmt.Sprintf("%s[%sm", escape, c.sequence()) +} + +func (c *Color) unformat() string { + //return fmt.Sprintf("%s[%dm", escape, Reset) + //for each element in sequence let's use the speficic reset escape, ou the generic one if not found + format := make([]string, len(c.params)) + for i, v := range c.params { + format[i] = strconv.Itoa(int(Reset)) + ra, ok := mapResetAttributes[v] + if ok { + format[i] = strconv.Itoa(int(ra)) + } + } + + return fmt.Sprintf("%s[%sm", escape, strings.Join(format, ";")) +} + +// DisableColor disables the color output. Useful to not change any existing +// code and still being able to output. Can be used for flags like +// "--no-color". To enable back use EnableColor() method. +func (c *Color) DisableColor() { + c.noColor = boolPtr(true) +} + +// EnableColor enables the color output. Use it in conjunction with +// DisableColor(). Otherwise, this method has no side effects. +func (c *Color) EnableColor() { + c.noColor = boolPtr(false) +} + +func (c *Color) isNoColorSet() bool { + // check first if we have user set action + if c.noColor != nil { + return *c.noColor + } + + // if not return the global option, which is disabled by default + return NoColor +} + +// Equals returns a boolean value indicating whether two colors are equal. +func (c *Color) Equals(c2 *Color) bool { + if c == nil && c2 == nil { + return true + } + if c == nil || c2 == nil { + return false + } + if len(c.params) != len(c2.params) { + return false + } + + for _, attr := range c.params { + if !c2.attrExists(attr) { + return false + } + } + + return true +} + +func (c *Color) attrExists(a Attribute) bool { + for _, attr := range c.params { + if attr == a { + return true + } + } + + return false +} + +func boolPtr(v bool) *bool { + return &v +} + +func getCachedColor(p Attribute) *Color { + colorsCacheMu.Lock() + defer colorsCacheMu.Unlock() + + c, ok := colorsCache[p] + if !ok { + c = New(p) + colorsCache[p] = c + } + + return c +} + +func colorPrint(format string, p Attribute, a ...interface{}) { + c := getCachedColor(p) + + if !strings.HasSuffix(format, "\n") { + format += "\n" + } + + if len(a) == 0 { + c.Print(format) + } else { + c.Printf(format, a...) + } +} + +func colorString(format string, p Attribute, a ...interface{}) string { + c := getCachedColor(p) + + if len(a) == 0 { + return c.SprintFunc()(format) + } + + return c.SprintfFunc()(format, a...) +} + +// Black is a convenient helper function to print with black foreground. A +// newline is appended to format by default. +func Black(format string, a ...interface{}) { colorPrint(format, FgBlack, a...) } + +// Red is a convenient helper function to print with red foreground. A +// newline is appended to format by default. +func Red(format string, a ...interface{}) { colorPrint(format, FgRed, a...) } + +// Green is a convenient helper function to print with green foreground. A +// newline is appended to format by default. +func Green(format string, a ...interface{}) { colorPrint(format, FgGreen, a...) } + +// Yellow is a convenient helper function to print with yellow foreground. +// A newline is appended to format by default. +func Yellow(format string, a ...interface{}) { colorPrint(format, FgYellow, a...) } + +// Blue is a convenient helper function to print with blue foreground. A +// newline is appended to format by default. +func Blue(format string, a ...interface{}) { colorPrint(format, FgBlue, a...) } + +// Magenta is a convenient helper function to print with magenta foreground. +// A newline is appended to format by default. +func Magenta(format string, a ...interface{}) { colorPrint(format, FgMagenta, a...) } + +// Cyan is a convenient helper function to print with cyan foreground. A +// newline is appended to format by default. +func Cyan(format string, a ...interface{}) { colorPrint(format, FgCyan, a...) } + +// White is a convenient helper function to print with white foreground. A +// newline is appended to format by default. +func White(format string, a ...interface{}) { colorPrint(format, FgWhite, a...) } + +// BlackString is a convenient helper function to return a string with black +// foreground. +func BlackString(format string, a ...interface{}) string { return colorString(format, FgBlack, a...) } + +// RedString is a convenient helper function to return a string with red +// foreground. +func RedString(format string, a ...interface{}) string { return colorString(format, FgRed, a...) } + +// GreenString is a convenient helper function to return a string with green +// foreground. +func GreenString(format string, a ...interface{}) string { return colorString(format, FgGreen, a...) } + +// YellowString is a convenient helper function to return a string with yellow +// foreground. +func YellowString(format string, a ...interface{}) string { return colorString(format, FgYellow, a...) } + +// BlueString is a convenient helper function to return a string with blue +// foreground. +func BlueString(format string, a ...interface{}) string { return colorString(format, FgBlue, a...) } + +// MagentaString is a convenient helper function to return a string with magenta +// foreground. +func MagentaString(format string, a ...interface{}) string { + return colorString(format, FgMagenta, a...) +} + +// CyanString is a convenient helper function to return a string with cyan +// foreground. +func CyanString(format string, a ...interface{}) string { return colorString(format, FgCyan, a...) } + +// WhiteString is a convenient helper function to return a string with white +// foreground. +func WhiteString(format string, a ...interface{}) string { return colorString(format, FgWhite, a...) } + +// HiBlack is a convenient helper function to print with hi-intensity black foreground. A +// newline is appended to format by default. +func HiBlack(format string, a ...interface{}) { colorPrint(format, FgHiBlack, a...) } + +// HiRed is a convenient helper function to print with hi-intensity red foreground. A +// newline is appended to format by default. +func HiRed(format string, a ...interface{}) { colorPrint(format, FgHiRed, a...) } + +// HiGreen is a convenient helper function to print with hi-intensity green foreground. A +// newline is appended to format by default. +func HiGreen(format string, a ...interface{}) { colorPrint(format, FgHiGreen, a...) } + +// HiYellow is a convenient helper function to print with hi-intensity yellow foreground. +// A newline is appended to format by default. +func HiYellow(format string, a ...interface{}) { colorPrint(format, FgHiYellow, a...) } + +// HiBlue is a convenient helper function to print with hi-intensity blue foreground. A +// newline is appended to format by default. +func HiBlue(format string, a ...interface{}) { colorPrint(format, FgHiBlue, a...) } + +// HiMagenta is a convenient helper function to print with hi-intensity magenta foreground. +// A newline is appended to format by default. +func HiMagenta(format string, a ...interface{}) { colorPrint(format, FgHiMagenta, a...) } + +// HiCyan is a convenient helper function to print with hi-intensity cyan foreground. A +// newline is appended to format by default. +func HiCyan(format string, a ...interface{}) { colorPrint(format, FgHiCyan, a...) } + +// HiWhite is a convenient helper function to print with hi-intensity white foreground. A +// newline is appended to format by default. +func HiWhite(format string, a ...interface{}) { colorPrint(format, FgHiWhite, a...) } + +// HiBlackString is a convenient helper function to return a string with hi-intensity black +// foreground. +func HiBlackString(format string, a ...interface{}) string { + return colorString(format, FgHiBlack, a...) +} + +// HiRedString is a convenient helper function to return a string with hi-intensity red +// foreground. +func HiRedString(format string, a ...interface{}) string { return colorString(format, FgHiRed, a...) } + +// HiGreenString is a convenient helper function to return a string with hi-intensity green +// foreground. +func HiGreenString(format string, a ...interface{}) string { + return colorString(format, FgHiGreen, a...) +} + +// HiYellowString is a convenient helper function to return a string with hi-intensity yellow +// foreground. +func HiYellowString(format string, a ...interface{}) string { + return colorString(format, FgHiYellow, a...) +} + +// HiBlueString is a convenient helper function to return a string with hi-intensity blue +// foreground. +func HiBlueString(format string, a ...interface{}) string { return colorString(format, FgHiBlue, a...) } + +// HiMagentaString is a convenient helper function to return a string with hi-intensity magenta +// foreground. +func HiMagentaString(format string, a ...interface{}) string { + return colorString(format, FgHiMagenta, a...) +} + +// HiCyanString is a convenient helper function to return a string with hi-intensity cyan +// foreground. +func HiCyanString(format string, a ...interface{}) string { return colorString(format, FgHiCyan, a...) } + +// HiWhiteString is a convenient helper function to return a string with hi-intensity white +// foreground. +func HiWhiteString(format string, a ...interface{}) string { + return colorString(format, FgHiWhite, a...) +} + +// sprintln is a helper function to format a string with fmt.Sprintln and trim the trailing newline. +func sprintln(a ...interface{}) string { + return strings.TrimSuffix(fmt.Sprintln(a...), "\n") +} diff --git a/vendor/github.com/fatih/color/color_windows.go b/vendor/github.com/fatih/color/color_windows.go new file mode 100644 index 00000000000..be01c558e50 --- /dev/null +++ b/vendor/github.com/fatih/color/color_windows.go @@ -0,0 +1,19 @@ +package color + +import ( + "os" + + "golang.org/x/sys/windows" +) + +func init() { + // Opt-in for ansi color support for current process. + // https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#output-sequences + var outMode uint32 + out := windows.Handle(os.Stdout.Fd()) + if err := windows.GetConsoleMode(out, &outMode); err != nil { + return + } + outMode |= windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING + _ = windows.SetConsoleMode(out, outMode) +} diff --git a/vendor/github.com/fatih/color/doc.go b/vendor/github.com/fatih/color/doc.go new file mode 100644 index 00000000000..9491ad5413c --- /dev/null +++ b/vendor/github.com/fatih/color/doc.go @@ -0,0 +1,134 @@ +/* +Package color is an ANSI color package to output colorized or SGR defined +output to the standard output. The API can be used in several way, pick one +that suits you. + +Use simple and default helper functions with predefined foreground colors: + + color.Cyan("Prints text in cyan.") + + // a newline will be appended automatically + color.Blue("Prints %s in blue.", "text") + + // More default foreground colors.. + color.Red("We have red") + color.Yellow("Yellow color too!") + color.Magenta("And many others ..") + + // Hi-intensity colors + color.HiGreen("Bright green color.") + color.HiBlack("Bright black means gray..") + color.HiWhite("Shiny white color!") + +However, there are times when custom color mixes are required. Below are some +examples to create custom color objects and use the print functions of each +separate color object. + + // Create a new color object + c := color.New(color.FgCyan).Add(color.Underline) + c.Println("Prints cyan text with an underline.") + + // Or just add them to New() + d := color.New(color.FgCyan, color.Bold) + d.Printf("This prints bold cyan %s\n", "too!.") + + + // Mix up foreground and background colors, create new mixes! + red := color.New(color.FgRed) + + boldRed := red.Add(color.Bold) + boldRed.Println("This will print text in bold red.") + + whiteBackground := red.Add(color.BgWhite) + whiteBackground.Println("Red text with White background.") + + // Use your own io.Writer output + color.New(color.FgBlue).Fprintln(myWriter, "blue color!") + + blue := color.New(color.FgBlue) + blue.Fprint(myWriter, "This will print text in blue.") + +You can create PrintXxx functions to simplify even more: + + // Create a custom print function for convenient + red := color.New(color.FgRed).PrintfFunc() + red("warning") + red("error: %s", err) + + // Mix up multiple attributes + notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() + notice("don't forget this...") + +You can also FprintXxx functions to pass your own io.Writer: + + blue := color.New(FgBlue).FprintfFunc() + blue(myWriter, "important notice: %s", stars) + + // Mix up with multiple attributes + success := color.New(color.Bold, color.FgGreen).FprintlnFunc() + success(myWriter, don't forget this...") + +Or create SprintXxx functions to mix strings with other non-colorized strings: + + yellow := New(FgYellow).SprintFunc() + red := New(FgRed).SprintFunc() + + fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error")) + + info := New(FgWhite, BgGreen).SprintFunc() + fmt.Printf("this %s rocks!\n", info("package")) + +Windows support is enabled by default. All Print functions work as intended. +However, only for color.SprintXXX functions, user should use fmt.FprintXXX and +set the output to color.Output: + + fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) + + info := New(FgWhite, BgGreen).SprintFunc() + fmt.Fprintf(color.Output, "this %s rocks!\n", info("package")) + +Using with existing code is possible. Just use the Set() method to set the +standard output to the given parameters. That way a rewrite of an existing +code is not required. + + // Use handy standard colors. + color.Set(color.FgYellow) + + fmt.Println("Existing text will be now in Yellow") + fmt.Printf("This one %s\n", "too") + + color.Unset() // don't forget to unset + + // You can mix up parameters + color.Set(color.FgMagenta, color.Bold) + defer color.Unset() // use it in your function + + fmt.Println("All text will be now bold magenta.") + +There might be a case where you want to disable color output (for example to +pipe the standard output of your app to somewhere else). `Color` has support to +disable colors both globally and for single color definition. For example +suppose you have a CLI app and a `--no-color` bool flag. You can easily disable +the color output with: + + var flagNoColor = flag.Bool("no-color", false, "Disable color output") + + if *flagNoColor { + color.NoColor = true // disables colorized output + } + +You can also disable the color by setting the NO_COLOR environment variable to any value. + +It also has support for single color definitions (local). You can +disable/enable color output on the fly: + + c := color.New(color.FgCyan) + c.Println("Prints cyan text") + + c.DisableColor() + c.Println("This is printed without any color") + + c.EnableColor() + c.Println("This prints again cyan...") +*/ +package color diff --git a/vendor/github.com/gemalto/flume/.golangci.yml b/vendor/github.com/gemalto/flume/.golangci.yml index 85a8e814013..344f33edfd2 100644 --- a/vendor/github.com/gemalto/flume/.golangci.yml +++ b/vendor/github.com/gemalto/flume/.golangci.yml @@ -193,15 +193,12 @@ linters: # to try out individual linters: golangci-lint run -E gocyclo,gosimple enable: - staticcheck - - deadcode - errcheck - gosimple - govet - ineffassign - - structcheck ## - typecheck # redundant? compiler does this - unused - - varcheck ## - bodyclose # its all false positives with requester and sling, which both close the body already - depguard ## - dogsled # checks for too many blank identifiers. don't care @@ -329,4 +326,4 @@ issues: # new-from-rev: REV # Show only new issues created in git patch with set file path. -# new-from-patch: path/to/patch/file \ No newline at end of file +# new-from-patch: path/to/patch/file diff --git a/vendor/github.com/gemalto/flume/Makefile b/vendor/github.com/gemalto/flume/Makefile index 49f41a7700c..a875085ac39 100644 --- a/vendor/github.com/gemalto/flume/Makefile +++ b/vendor/github.com/gemalto/flume/Makefile @@ -48,7 +48,6 @@ update: tools: # installs tools used during build go get -u golang.org/x/tools/cmd/cover - sh -c "$$(wget -O - -q https://install.goreleaser.com/github.com/golangci/golangci-lint.sh || echo exit 2)" -- -b $(shell go env GOPATH)/bin $(GOLANGCI_LINT_VERSION) + sh -c "$$(wget -O - -q https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh || echo exit 2)" -- -b $(shell go env GOPATH)/bin $(GOLANGCI_LINT_VERSION) .PHONY: all build builddir run artifacts vet lint clean fmt test testall testreport up down pull builder runc ci bash fish image prep vendor.update vendor.ensure tools buildtools migratetool db.migrate - diff --git a/vendor/github.com/gemalto/flume/config.go b/vendor/github.com/gemalto/flume/config.go index e423d86bf13..e2740f53fb5 100644 --- a/vendor/github.com/gemalto/flume/config.go +++ b/vendor/github.com/gemalto/flume/config.go @@ -16,10 +16,10 @@ var DefaultConfigEnvVars = []string{"FLUME"} // ConfigFromEnv configures flume from environment variables. // It should be called from main(): // -// func main() { -// flume.ConfigFromEnv() -// ... -// } +// func main() { +// flume.ConfigFromEnv() +// ... +// } // // It searches envvars for the first environment // variable that is set, and attempts to parse the value. @@ -30,7 +30,6 @@ var DefaultConfigEnvVars = []string{"FLUME"} // fails, an error is printed to stdout, and the error is returned. // // If envvars is empty, it defaults to DefaultConfigEnvVars. -// func ConfigFromEnv(envvars ...string) error { if len(envvars) == 0 { envvars = DefaultConfigEnvVars @@ -58,11 +57,11 @@ func ConfigFromEnv(envvars ...string) error { // Configs can be unmarshaled from JSON, making it a convenient // way to configure most logging options from env vars or files, i.e.: // -// err := flume.ConfigString(os.Getenv("flume")) +// err := flume.ConfigString(os.Getenv("flume")) // // Configs can be created and applied programmatically: // -// err := flume.Configure(flume.Config{}) +// err := flume.Configure(flume.Config{}) // // Defaults are appropriate for a JSON encoded production logger: // @@ -74,13 +73,13 @@ func ConfigFromEnv(envvars ...string) error { // An alternate set of defaults, more appropriate for development environments, // can be configured with `Config{Development:true}`: // -// err := flume.Configure(flume.Config{Development:true}) +// err := flume.Configure(flume.Config{Development:true}) // // - colorized terminal encoder // - short timestamps // - call sites are logged // -// err := flume.Configure(flume.Config{Development:true}) +// err := flume.Configure(flume.Config{Development:true}) // // Any of the other configuration options can be specified to override // the defaults. @@ -185,9 +184,8 @@ func NewDevelopmentEncoderConfig() *EncoderConfig { // as a simple time of day, without a date. Intended for development and testing. // Not good in a production system, where you probably need to know the date. // -// encConfig := flume.EncoderConfig{} -// encConfig.EncodeTime = flume.JustTimeEncoder -// +// encConfig := flume.EncoderConfig{} +// encConfig.EncodeTime = flume.JustTimeEncoder func JustTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(t.Format("15:04:05.000")) } @@ -195,9 +193,8 @@ func JustTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { // AbbrLevelEncoder encodes logging levels to the strings in the log entries. // Encodes levels as 3-char abbreviations in upper case. // -// encConfig := flume.EncoderConfig{} -// encConfig.EncodeTime = flume.AbbrLevelEncoder -// +// encConfig := flume.EncoderConfig{} +// encConfig.EncodeTime = flume.AbbrLevelEncoder func AbbrLevelEncoder(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { switch l { case zapcore.DebugLevel: diff --git a/vendor/github.com/gemalto/flume/console_encoder.go b/vendor/github.com/gemalto/flume/console_encoder.go index c95b816d785..eb89a1fdc75 100644 --- a/vendor/github.com/gemalto/flume/console_encoder.go +++ b/vendor/github.com/gemalto/flume/console_encoder.go @@ -87,8 +87,7 @@ func NewConsoleEncoder(cfg *EncoderConfig) Encoder { // // `github.com/mgutz/ansi` is a convenient package for getting color codes, e.g.: // -// ansi.ColorCode("red") -// +// ansi.ColorCode("red") func NewColorizedConsoleEncoder(cfg *EncoderConfig, colorizer Colorizer) Encoder { e := NewConsoleEncoder(cfg).(*consoleEncoder) e.colorizer = colorizer diff --git a/vendor/github.com/gemalto/flume/core.go b/vendor/github.com/gemalto/flume/core.go index ce61c8398cb..dc5b9fb2410 100644 --- a/vendor/github.com/gemalto/flume/core.go +++ b/vendor/github.com/gemalto/flume/core.go @@ -238,8 +238,7 @@ func (l *Core) IsInfo() bool { // // args should be alternative keys and values. keys should be strings. // -// reqLogger := l.With("requestID", reqID) -// +// reqLogger := l.With("requestID", reqID) func (l *Core) With(args ...interface{}) Logger { return l.WithArgs(args...) } diff --git a/vendor/github.com/gemalto/flume/doc.go b/vendor/github.com/gemalto/flume/doc.go index 02d246b824c..133211bc23c 100644 --- a/vendor/github.com/gemalto/flume/doc.go +++ b/vendor/github.com/gemalto/flume/doc.go @@ -11,41 +11,41 @@ // importers can entirely replace flume if they wish. Alternately, importers can use flume to configure // the library's log output, and/or redirect it into the overall program's log stream. // -// Logging +// # Logging // // This package does not offer package level log functions, so you need to create a logger instance first: // A common pattern is to create a single, package-wide logger, named after the package: // -// var log = flume.New("mypkg") +// var log = flume.New("mypkg") // // Then, write some logs: // -// log.Debug("created user", "username", "frank", "role", "admin") +// log.Debug("created user", "username", "frank", "role", "admin") // // Logs have a message, then matched pairs of key/value properties. Child loggers can be created // and pre-seeded with a set of properties: // -// reqLogger := log.With("remoteAddr", req.RemoteAddr) +// reqLogger := log.With("remoteAddr", req.RemoteAddr) // // Expensive log events can be avoid by explicitly checking level: // -// if log.IsDebug() { -// log.Debug("created resource", "resource", resource.ExpensiveToString()) -// } +// if log.IsDebug() { +// log.Debug("created resource", "resource", resource.ExpensiveToString()) +// } // // Loggers can be bound to context.Context, which is convenient for carrying // per-transaction loggers (pre-seeded with transaction specific context) through layers of request // processing code: // -// ctx = flume.WithLogger(ctx, log.With("transactionID", tid)) -// // ...later... -// flume.FromContext(ctx).Info("Request handled.") +// ctx = flume.WithLogger(ctx, log.With("transactionID", tid)) +// // ...later... +// flume.FromContext(ctx).Info("Request handled.") // // The standard Logger interface only supports 3 levels of log, DBG, INF, and ERR. This is inspired by // this article: https://dave.cheney.net/2015/11/05/lets-talk-about-logging. However, you can create // instances of DeprecatedLogger instead, which support more levels. // -// Configuration +// # Configuration // // There are several package level functions which reconfigure logging output. They control which // levels are discarded, which fields are included in each log entry, and how those fields are rendered, @@ -53,64 +53,78 @@ // // To configure logging settings from environment variables, call the configuration function from main(): // -// flume.ConfigFromEnv() +// flume.ConfigFromEnv() // // This reads the log configuration from the environment variable "FLUME" (the default, which can be // overridden). The value is JSON, e.g.: // -// {"level":"INF","levels":"http=DBG","development"="true"} +// {"level":"INF","levels":"http=DBG","development"="true"} // // The properties of the config string: // -// - "level": ERR, INF, or DBG. The default level for all loggers. -// - "levels": A string configuring log levels for specific loggers, overriding the default level. -// See note below for syntax. -// - "development": true or false. In development mode, the defaults for the other -// settings change to be more suitable for developers at a terminal (colorized, multiline, human -// readable, etc). See note below for exact defaults. -// - "addCaller": true or false. Adds call site information to log entries (file and line). -// - "encoding": json, ltsv, term, or term-color. Configures how log entries are encoded in the output. -// "term" and "term-color" are multi-line, human-friendly -// formats, intended for terminal output. -// - "encoderConfig": a JSON object which configures advanced encoding settings, like how timestamps -// are formatted. See docs for go.uber.org/zap/zapcore/EncoderConfig -// -// - "messageKey": the label of the message property of the log entry. If empty, message is omitted. -// - "levelKey": the label of the level property of the log entry. If empty, level is omitted. -// - "timeKey": the label of the timestamp of the log entry. If empty, timestamp is omitted. -// - "nameKey": the label of the logger name in the log entry. If empty, logger name is omitted. -// - "callerKey": the label of the logger name in the log entry. If empty, logger name is omitted. -// - "lineEnding": the end of each log output line. -// - "levelEncoder": capital, capitalColor, color, lower, or abbr. Controls how the log entry level -// is rendered. "abbr" renders 3-letter abbreviations, like ERR and INF. -// - "timeEncoder": iso8601, millis, nanos, unix, or justtime. Controls how timestamps are rendered. -// "millis", "nanos", and "unix" are since UNIX epoch. "unix" is in floating point seconds. -// "justtime" omits the date, and just prints the time in the format "15:04:05.000". -// - "durationEncoder": string, nanos, or seconds. Controls how time.Duration values are rendered. -// - "callerEncoder": full or short. Controls how the call site is rendered. -// "full" includes the entire package path, "short" only includes the last folder of the package. +// - "level": ERR, INF, or DBG. The default level for all loggers. +// +// - "levels": A string configuring log levels for specific loggers, overriding the default level. +// See note below for syntax. +// +// - "development": true or false. In development mode, the defaults for the other +// settings change to be more suitable for developers at a terminal (colorized, multiline, human +// readable, etc). See note below for exact defaults. +// +// - "addCaller": true or false. Adds call site information to log entries (file and line). +// +// - "encoding": json, ltsv, term, or term-color. Configures how log entries are encoded in the output. +// "term" and "term-color" are multi-line, human-friendly +// formats, intended for terminal output. +// +// - "encoderConfig": a JSON object which configures advanced encoding settings, like how timestamps +// are formatted. See docs for go.uber.org/zap/zapcore/EncoderConfig +// +// - "messageKey": the label of the message property of the log entry. If empty, message is omitted. +// +// - "levelKey": the label of the level property of the log entry. If empty, level is omitted. +// +// - "timeKey": the label of the timestamp of the log entry. If empty, timestamp is omitted. +// +// - "nameKey": the label of the logger name in the log entry. If empty, logger name is omitted. +// +// - "callerKey": the label of the logger name in the log entry. If empty, logger name is omitted. +// +// - "lineEnding": the end of each log output line. +// +// - "levelEncoder": capital, capitalColor, color, lower, or abbr. Controls how the log entry level +// is rendered. "abbr" renders 3-letter abbreviations, like ERR and INF. +// +// - "timeEncoder": iso8601, millis, nanos, unix, or justtime. Controls how timestamps are rendered. +// "millis", "nanos", and "unix" are since UNIX epoch. "unix" is in floating point seconds. +// "justtime" omits the date, and just prints the time in the format "15:04:05.000". +// +// - "durationEncoder": string, nanos, or seconds. Controls how time.Duration values are rendered. +// +// - "callerEncoder": full or short. Controls how the call site is rendered. +// "full" includes the entire package path, "short" only includes the last folder of the package. // // Defaults: // -// { -// "level":"INF", -// "levels":"", -// "development":false, -// "addCaller":false, -// "encoding":"term-color", -// "encoderConfig":{ -// "messageKey":"msg", -// "levelKey":"level", -// "timeKey":"time", -// "nameKey":"name", -// "callerKey":"caller", -// "lineEnding":"\n", -// "levelEncoder":"abbr", -// "timeEncoder":"iso8601", -// "durationEncoder":"seconds", -// "callerEncoder":"short", -// } -// } +// { +// "level":"INF", +// "levels":"", +// "development":false, +// "addCaller":false, +// "encoding":"term-color", +// "encoderConfig":{ +// "messageKey":"msg", +// "levelKey":"level", +// "timeKey":"time", +// "nameKey":"name", +// "callerKey":"caller", +// "lineEnding":"\n", +// "levelEncoder":"abbr", +// "timeEncoder":"iso8601", +// "durationEncoder":"seconds", +// "callerEncoder":"short", +// } +// } // // These defaults are only applied if one of the configuration functions is called, like ConfigFromEnv(), ConfigString(), // Configure(), or LevelsString(). Initially, all loggers are configured to discard everything, following @@ -120,21 +134,21 @@ // // Development mode: if "development"=true, the defaults for the rest of the settings change, equivalent to: // -// { -// "addCaller":true, -// "encoding":"term-color", -// "encodingConfig": { -// "timeEncoder":"justtime", -// "durationEncoder":"string", -// } -// } +// { +// "addCaller":true, +// "encoding":"term-color", +// "encodingConfig": { +// "timeEncoder":"justtime", +// "durationEncoder":"string", +// } +// } // // The "levels" value is a list of key=value pairs, configuring the level of individual named loggers. // If the key is "*", it sets the default level. If "level" and "levels" both configure the default // level, "levels" wins. // Examples: // -// * // set the default level to ALL, equivalent to {"level"="ALL"} +// - // set the default level to ALL, equivalent to {"level"="ALL"} // *=INF // same, but set default level to INF // *,sql=WRN // set default to ALL, set "sql" logger to WRN // *=INF,http=ALL // set default to INF, set "http" to ALL @@ -142,7 +156,7 @@ // *=INF,-http // set default to INF, set "http" to OFF // http=INF // leave default setting unchanged. // -// Factories +// # Factories // // Most usages of flume will use its package functions. The package functions delegate to an internal // instance of Factory, which a the logger registry. You can create and manage your own instance of diff --git a/vendor/github.com/gemalto/flume/factory.go b/vendor/github.com/gemalto/flume/factory.go index 28676a9fb67..fd93f9bb836 100644 --- a/vendor/github.com/gemalto/flume/factory.go +++ b/vendor/github.com/gemalto/flume/factory.go @@ -236,28 +236,28 @@ func parseConfigString(s string) map[string]interface{} { // can set the default log level, and can explicitly set the log level for individual // loggers. // -// Directives +// # Directives // // - Default level: Use the `*` directive to set the default log level. Examples: // -// * // set the default log level to debug -// -* // set the default log level to off +// - // set the default log level to debug +// -* // set the default log level to off // -// If the `*` directive is omitted, the default log level will be set to info. -// - Logger level: Use the name of the logger to set the log level for a specific -// logger. Examples: +// If the `*` directive is omitted, the default log level will be set to info. // -// http // set the http logger to debug -// -http // set the http logger to off -// http=INF // set the http logger to info +// - Logger level: Use the name of the logger to set the log level for a specific +// logger. Examples: // -// Multiple directives can be included, separated by commas. Examples: +// http // set the http logger to debug +// -http // set the http logger to off +// http=INF // set the http logger to info // -// http // set http logger to debug -// http,sql // set http and sql logger to debug -// *,-http,sql=INF // set the default level to debug, disable the http logger, -// // and set the sql logger to info +// Multiple directives can be included, separated by commas. Examples: // +// http // set http logger to debug +// http,sql // set http and sql logger to debug +// *,-http,sql=INF // set the default level to debug, disable the http logger, +// // and set the sql logger to info func (r *Factory) LevelsString(s string) error { m := parseConfigString(s) levelMap := map[string]Level{} diff --git a/vendor/github.com/gemalto/flume/logger_writer.go b/vendor/github.com/gemalto/flume/logger_writer.go index 618a2dedf49..2ac683a22cf 100644 --- a/vendor/github.com/gemalto/flume/logger_writer.go +++ b/vendor/github.com/gemalto/flume/logger_writer.go @@ -9,9 +9,8 @@ import ( // like that of testing.T.Log() and fmt/log.Println(). // It can be used to redirect flumes *output* to some other logger. // -// SetOut(LogFuncWriter(fmt.Println, true)) -// SetOut(LogFuncWriter(t.Log, true)) -// +// SetOut(LogFuncWriter(fmt.Println, true)) +// SetOut(LogFuncWriter(t.Log, true)) func LogFuncWriter(l func(args ...interface{}), trimSpace bool) io.Writer { return &logWriter{lf: l, trimSpace: trimSpace} } @@ -19,10 +18,9 @@ func LogFuncWriter(l func(args ...interface{}), trimSpace bool) io.Writer { // LoggerFuncWriter is a writer which writes lines to a logging function with // a signature like that of flume.Logger's functions, like Info(), Debug(), and Error(). // -// http.Server{ -// ErrorLog: log.New(LoggerFuncWriter(flume.New("http").Error), "", 0), -// } -// +// http.Server{ +// ErrorLog: log.New(LoggerFuncWriter(flume.New("http").Error), "", 0), +// } func LoggerFuncWriter(l func(msg string, kvpairs ...interface{})) io.Writer { return &loggerWriter{lf: l} } diff --git a/vendor/github.com/gemalto/flume/ltsv_encoder.go b/vendor/github.com/gemalto/flume/ltsv_encoder.go index e58f2cb7a14..2515edc1da7 100644 --- a/vendor/github.com/gemalto/flume/ltsv_encoder.go +++ b/vendor/github.com/gemalto/flume/ltsv_encoder.go @@ -243,7 +243,6 @@ func (enc *ltsvEncoder) AppendUint64(val uint64) { enc.buf.AppendUint(val) } -// // AddComplex64 implements zapcore.ObjectEncoder func (enc *ltsvEncoder) AddComplex64(k string, v complex64) { enc.AddComplex128(k, complex128(v)) } @@ -424,6 +423,7 @@ func (enc *ltsvEncoder) appendFloat(val float64, bitSize int) { // safeAddString appends a string to the internal buffer. // If `key`, colons are replaced with underscores, and newlines and tabs are escaped // If not `key`, only newlines and tabs are escaped, unless configured otherwise +// //nolint:dupl func (enc *ltsvEncoder) safeAddString(s string, key bool) { for i := 0; i < len(s); { @@ -465,6 +465,7 @@ func (enc *ltsvEncoder) safeAddString(s string, key bool) { } // safeAddByteString is no-alloc equivalent of safeAddString(string(s)) for s []byte. +// //nolint:dupl func (enc *ltsvEncoder) safeAddByteString(s []byte, key bool) { for i := 0; i < len(s); { diff --git a/vendor/github.com/go-openapi/jsonpointer/.golangci.yml b/vendor/github.com/go-openapi/jsonpointer/.golangci.yml new file mode 100644 index 00000000000..22f8d21cca1 --- /dev/null +++ b/vendor/github.com/go-openapi/jsonpointer/.golangci.yml @@ -0,0 +1,61 @@ +linters-settings: + govet: + check-shadowing: true + golint: + min-confidence: 0 + gocyclo: + min-complexity: 45 + maligned: + suggest-new: true + dupl: + threshold: 200 + goconst: + min-len: 2 + min-occurrences: 3 + +linters: + enable-all: true + disable: + - maligned + - unparam + - lll + - gochecknoinits + - gochecknoglobals + - funlen + - godox + - gocognit + - whitespace + - wsl + - wrapcheck + - testpackage + - nlreturn + - gomnd + - exhaustivestruct + - goerr113 + - errorlint + - nestif + - godot + - gofumpt + - paralleltest + - tparallel + - thelper + - ifshort + - exhaustruct + - varnamelen + - gci + - depguard + - errchkjson + - inamedparam + - nonamedreturns + - musttag + - ireturn + - forcetypeassert + - cyclop + # deprecated linters + - deadcode + - interfacer + - scopelint + - varcheck + - structcheck + - golint + - nosnakecase diff --git a/vendor/github.com/go-openapi/jsonpointer/README.md b/vendor/github.com/go-openapi/jsonpointer/README.md index 813788aff1c..0108f1d572d 100644 --- a/vendor/github.com/go-openapi/jsonpointer/README.md +++ b/vendor/github.com/go-openapi/jsonpointer/README.md @@ -1,6 +1,10 @@ -# gojsonpointer [![Build Status](https://travis-ci.org/go-openapi/jsonpointer.svg?branch=master)](https://travis-ci.org/go-openapi/jsonpointer) [![codecov](https://codecov.io/gh/go-openapi/jsonpointer/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonpointer) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) +# gojsonpointer [![Build Status](https://github.com/go-openapi/jsonpointer/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/jsonpointer/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/jsonpointer/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonpointer) + +[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) +[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonpointer/master/LICENSE) +[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/jsonpointer.svg)](https://pkg.go.dev/github.com/go-openapi/jsonpointer) +[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/jsonpointer)](https://goreportcard.com/report/github.com/go-openapi/jsonpointer) -[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonpointer/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/jsonpointer?status.svg)](http://godoc.org/github.com/go-openapi/jsonpointer) An implementation of JSON Pointer - Go language ## Status diff --git a/vendor/github.com/go-openapi/jsonpointer/pointer.go b/vendor/github.com/go-openapi/jsonpointer/pointer.go index 7df9853def6..d970c7cf448 100644 --- a/vendor/github.com/go-openapi/jsonpointer/pointer.go +++ b/vendor/github.com/go-openapi/jsonpointer/pointer.go @@ -26,6 +26,7 @@ package jsonpointer import ( + "encoding/json" "errors" "fmt" "reflect" @@ -40,6 +41,7 @@ const ( pointerSeparator = `/` invalidStart = `JSON pointer must be empty or start with a "` + pointerSeparator + notFound = `Can't find the pointer in the document` ) var jsonPointableType = reflect.TypeOf(new(JSONPointable)).Elem() @@ -48,13 +50,13 @@ var jsonSetableType = reflect.TypeOf(new(JSONSetable)).Elem() // JSONPointable is an interface for structs to implement when they need to customize the // json pointer process type JSONPointable interface { - JSONLookup(string) (interface{}, error) + JSONLookup(string) (any, error) } // JSONSetable is an interface for structs to implement when they need to customize the // json pointer process type JSONSetable interface { - JSONSet(string, interface{}) error + JSONSet(string, any) error } // New creates a new json pointer for the given string @@ -81,9 +83,7 @@ func (p *Pointer) parse(jsonPointerString string) error { err = errors.New(invalidStart) } else { referenceTokens := strings.Split(jsonPointerString, pointerSeparator) - for _, referenceToken := range referenceTokens[1:] { - p.referenceTokens = append(p.referenceTokens, referenceToken) - } + p.referenceTokens = append(p.referenceTokens, referenceTokens[1:]...) } } @@ -91,38 +91,58 @@ func (p *Pointer) parse(jsonPointerString string) error { } // Get uses the pointer to retrieve a value from a JSON document -func (p *Pointer) Get(document interface{}) (interface{}, reflect.Kind, error) { +func (p *Pointer) Get(document any) (any, reflect.Kind, error) { return p.get(document, swag.DefaultJSONNameProvider) } // Set uses the pointer to set a value from a JSON document -func (p *Pointer) Set(document interface{}, value interface{}) (interface{}, error) { +func (p *Pointer) Set(document any, value any) (any, error) { return document, p.set(document, value, swag.DefaultJSONNameProvider) } // GetForToken gets a value for a json pointer token 1 level deep -func GetForToken(document interface{}, decodedToken string) (interface{}, reflect.Kind, error) { +func GetForToken(document any, decodedToken string) (any, reflect.Kind, error) { return getSingleImpl(document, decodedToken, swag.DefaultJSONNameProvider) } // SetForToken gets a value for a json pointer token 1 level deep -func SetForToken(document interface{}, decodedToken string, value interface{}) (interface{}, error) { +func SetForToken(document any, decodedToken string, value any) (any, error) { return document, setSingleImpl(document, value, decodedToken, swag.DefaultJSONNameProvider) } -func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) { +func isNil(input any) bool { + if input == nil { + return true + } + + kind := reflect.TypeOf(input).Kind() + switch kind { //nolint:exhaustive + case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan: + return reflect.ValueOf(input).IsNil() + default: + return false + } +} + +func getSingleImpl(node any, decodedToken string, nameProvider *swag.NameProvider) (any, reflect.Kind, error) { rValue := reflect.Indirect(reflect.ValueOf(node)) kind := rValue.Kind() + if isNil(node) { + return nil, kind, fmt.Errorf("nil value has not field %q", decodedToken) + } - if rValue.Type().Implements(jsonPointableType) { - r, err := node.(JSONPointable).JSONLookup(decodedToken) + switch typed := node.(type) { + case JSONPointable: + r, err := typed.JSONLookup(decodedToken) if err != nil { return nil, kind, err } return r, kind, nil + case *any: // case of a pointer to interface, that is not resolved by reflect.Indirect + return getSingleImpl(*typed, decodedToken, nameProvider) } - switch kind { + switch kind { //nolint:exhaustive case reflect.Struct: nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) if !ok { @@ -159,7 +179,7 @@ func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.Nam } -func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *swag.NameProvider) error { +func setSingleImpl(node, data any, decodedToken string, nameProvider *swag.NameProvider) error { rValue := reflect.Indirect(reflect.ValueOf(node)) if ns, ok := node.(JSONSetable); ok { // pointer impl @@ -170,7 +190,7 @@ func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *sw return node.(JSONSetable).JSONSet(decodedToken, data) } - switch rValue.Kind() { + switch rValue.Kind() { //nolint:exhaustive case reflect.Struct: nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) if !ok { @@ -210,7 +230,7 @@ func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *sw } -func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) { +func (p *Pointer) get(node any, nameProvider *swag.NameProvider) (any, reflect.Kind, error) { if nameProvider == nil { nameProvider = swag.DefaultJSONNameProvider @@ -231,8 +251,7 @@ func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interf if err != nil { return nil, knd, err } - node, kind = r, knd - + node = r } rValue := reflect.ValueOf(node) @@ -241,11 +260,11 @@ func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interf return node, kind, nil } -func (p *Pointer) set(node, data interface{}, nameProvider *swag.NameProvider) error { +func (p *Pointer) set(node, data any, nameProvider *swag.NameProvider) error { knd := reflect.ValueOf(node).Kind() if knd != reflect.Ptr && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array { - return fmt.Errorf("only structs, pointers, maps and slices are supported for setting values") + return errors.New("only structs, pointers, maps and slices are supported for setting values") } if nameProvider == nil { @@ -284,7 +303,7 @@ func (p *Pointer) set(node, data interface{}, nameProvider *swag.NameProvider) e continue } - switch kind { + switch kind { //nolint:exhaustive case reflect.Struct: nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) if !ok { @@ -363,6 +382,128 @@ func (p *Pointer) String() string { return pointerString } +func (p *Pointer) Offset(document string) (int64, error) { + dec := json.NewDecoder(strings.NewReader(document)) + var offset int64 + for _, ttk := range p.DecodedTokens() { + tk, err := dec.Token() + if err != nil { + return 0, err + } + switch tk := tk.(type) { + case json.Delim: + switch tk { + case '{': + offset, err = offsetSingleObject(dec, ttk) + if err != nil { + return 0, err + } + case '[': + offset, err = offsetSingleArray(dec, ttk) + if err != nil { + return 0, err + } + default: + return 0, fmt.Errorf("invalid token %#v", tk) + } + default: + return 0, fmt.Errorf("invalid token %#v", tk) + } + } + return offset, nil +} + +func offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) { + for dec.More() { + offset := dec.InputOffset() + tk, err := dec.Token() + if err != nil { + return 0, err + } + switch tk := tk.(type) { + case json.Delim: + switch tk { + case '{': + if err = drainSingle(dec); err != nil { + return 0, err + } + case '[': + if err = drainSingle(dec); err != nil { + return 0, err + } + } + case string: + if tk == decodedToken { + return offset, nil + } + default: + return 0, fmt.Errorf("invalid token %#v", tk) + } + } + return 0, fmt.Errorf("token reference %q not found", decodedToken) +} + +func offsetSingleArray(dec *json.Decoder, decodedToken string) (int64, error) { + idx, err := strconv.Atoi(decodedToken) + if err != nil { + return 0, fmt.Errorf("token reference %q is not a number: %v", decodedToken, err) + } + var i int + for i = 0; i < idx && dec.More(); i++ { + tk, err := dec.Token() + if err != nil { + return 0, err + } + + if delim, isDelim := tk.(json.Delim); isDelim { + switch delim { + case '{': + if err = drainSingle(dec); err != nil { + return 0, err + } + case '[': + if err = drainSingle(dec); err != nil { + return 0, err + } + } + } + } + + if !dec.More() { + return 0, fmt.Errorf("token reference %q not found", decodedToken) + } + return dec.InputOffset(), nil +} + +// drainSingle drains a single level of object or array. +// The decoder has to guarantee the beginning delim (i.e. '{' or '[') has been consumed. +func drainSingle(dec *json.Decoder) error { + for dec.More() { + tk, err := dec.Token() + if err != nil { + return err + } + if delim, isDelim := tk.(json.Delim); isDelim { + switch delim { + case '{': + if err = drainSingle(dec); err != nil { + return err + } + case '[': + if err = drainSingle(dec); err != nil { + return err + } + } + } + } + + // Consumes the ending delim + if _, err := dec.Token(); err != nil { + return err + } + return nil +} + // Specific JSON pointer encoding here // ~0 => ~ // ~1 => / @@ -377,14 +518,14 @@ const ( // Unescape unescapes a json pointer reference token string to the original representation func Unescape(token string) string { - step1 := strings.Replace(token, encRefTok1, decRefTok1, -1) - step2 := strings.Replace(step1, encRefTok0, decRefTok0, -1) + step1 := strings.ReplaceAll(token, encRefTok1, decRefTok1) + step2 := strings.ReplaceAll(step1, encRefTok0, decRefTok0) return step2 } // Escape escapes a pointer reference token string func Escape(token string) string { - step1 := strings.Replace(token, decRefTok0, encRefTok0, -1) - step2 := strings.Replace(step1, decRefTok1, encRefTok1, -1) + step1 := strings.ReplaceAll(token, decRefTok0, encRefTok0) + step2 := strings.ReplaceAll(step1, decRefTok1, encRefTok1) return step2 } diff --git a/vendor/github.com/go-openapi/jsonreference/.golangci.yml b/vendor/github.com/go-openapi/jsonreference/.golangci.yml index 013fc1943a9..22f8d21cca1 100644 --- a/vendor/github.com/go-openapi/jsonreference/.golangci.yml +++ b/vendor/github.com/go-openapi/jsonreference/.golangci.yml @@ -1,50 +1,61 @@ linters-settings: govet: check-shadowing: true + golint: + min-confidence: 0 gocyclo: - min-complexity: 30 + min-complexity: 45 maligned: suggest-new: true dupl: - threshold: 100 + threshold: 200 goconst: min-len: 2 - min-occurrences: 4 - paralleltest: - ignore-missing: true + min-occurrences: 3 + linters: enable-all: true disable: - maligned + - unparam - lll + - gochecknoinits - gochecknoglobals + - funlen - godox - gocognit - whitespace - wsl - - funlen - - gochecknoglobals - - gochecknoinits - - scopelint - wrapcheck - - exhaustivestruct - - exhaustive - - nlreturn - testpackage - - gci - - gofumpt - - goerr113 + - nlreturn - gomnd - - tparallel + - exhaustivestruct + - goerr113 + - errorlint - nestif - godot - - errorlint - - varcheck - - interfacer - - deadcode - - golint + - gofumpt + - paralleltest + - tparallel + - thelper - ifshort + - exhaustruct + - varnamelen + - gci + - depguard + - errchkjson + - inamedparam + - nonamedreturns + - musttag + - ireturn + - forcetypeassert + - cyclop + # deprecated linters + - deadcode + - interfacer + - scopelint + - varcheck - structcheck + - golint - nosnakecase - - varnamelen - - exhaustruct diff --git a/vendor/github.com/go-openapi/jsonreference/README.md b/vendor/github.com/go-openapi/jsonreference/README.md index b94753aa527..c7fc2049c1d 100644 --- a/vendor/github.com/go-openapi/jsonreference/README.md +++ b/vendor/github.com/go-openapi/jsonreference/README.md @@ -1,15 +1,19 @@ -# gojsonreference [![Build Status](https://travis-ci.org/go-openapi/jsonreference.svg?branch=master)](https://travis-ci.org/go-openapi/jsonreference) [![codecov](https://codecov.io/gh/go-openapi/jsonreference/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonreference) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) +# gojsonreference [![Build Status](https://github.com/go-openapi/jsonreference/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/jsonreference/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/jsonreference/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonreference) + +[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) +[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonreference/master/LICENSE) +[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/jsonreference.svg)](https://pkg.go.dev/github.com/go-openapi/jsonreference) +[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/jsonreference)](https://goreportcard.com/report/github.com/go-openapi/jsonreference) -[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonreference/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/jsonreference?status.svg)](http://godoc.org/github.com/go-openapi/jsonreference) An implementation of JSON Reference - Go language ## Status Feature complete. Stable API ## Dependencies -https://github.com/go-openapi/jsonpointer +* https://github.com/go-openapi/jsonpointer ## References -http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07 -http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03 +* http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07 +* http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03 diff --git a/vendor/github.com/go-openapi/swag/.gitignore b/vendor/github.com/go-openapi/swag/.gitignore index d69b53accc5..c4b1b64f04e 100644 --- a/vendor/github.com/go-openapi/swag/.gitignore +++ b/vendor/github.com/go-openapi/swag/.gitignore @@ -2,3 +2,4 @@ secrets.yml vendor Godeps .idea +*.out diff --git a/vendor/github.com/go-openapi/swag/.golangci.yml b/vendor/github.com/go-openapi/swag/.golangci.yml index bf503e40001..80e2be0042f 100644 --- a/vendor/github.com/go-openapi/swag/.golangci.yml +++ b/vendor/github.com/go-openapi/swag/.golangci.yml @@ -4,14 +4,14 @@ linters-settings: golint: min-confidence: 0 gocyclo: - min-complexity: 25 + min-complexity: 45 maligned: suggest-new: true dupl: - threshold: 100 + threshold: 200 goconst: min-len: 3 - min-occurrences: 2 + min-occurrences: 3 linters: enable-all: true @@ -20,35 +20,41 @@ linters: - lll - gochecknoinits - gochecknoglobals - - nlreturn - - testpackage + - funlen + - godox + - gocognit + - whitespace + - wsl - wrapcheck + - testpackage + - nlreturn - gomnd - - exhaustive - exhaustivestruct - goerr113 - - wsl - - whitespace - - gofumpt - - godot + - errorlint - nestif - - godox - - funlen - - gci - - gocognit + - godot + - gofumpt - paralleltest + - tparallel - thelper - ifshort - - gomoddirectives - - cyclop - - forcetypeassert - - ireturn - - tagliatelle - - varnamelen - - goimports - - tenv - - golint - exhaustruct - - nilnil + - varnamelen + - gci + - depguard + - errchkjson + - inamedparam - nonamedreturns + - musttag + - ireturn + - forcetypeassert + - cyclop + # deprecated linters + - deadcode + - interfacer + - scopelint + - varcheck + - structcheck + - golint - nosnakecase diff --git a/vendor/github.com/go-openapi/swag/BENCHMARK.md b/vendor/github.com/go-openapi/swag/BENCHMARK.md new file mode 100644 index 00000000000..3fa25c33cfd --- /dev/null +++ b/vendor/github.com/go-openapi/swag/BENCHMARK.md @@ -0,0 +1,52 @@ +# Benchmarks + +## Name mangling utilities + +```bash +go test -bench XXX -run XXX -benchtime 30s +``` + +### Benchmarks at b3e7a5386f996177e4808f11acb2aa93a0f660df + +``` +goos: linux +goarch: amd64 +pkg: github.com/go-openapi/swag +cpu: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz +BenchmarkToXXXName/ToGoName-4 862623 44101 ns/op 10450 B/op 732 allocs/op +BenchmarkToXXXName/ToVarName-4 853656 40728 ns/op 10468 B/op 734 allocs/op +BenchmarkToXXXName/ToFileName-4 1268312 27813 ns/op 9785 B/op 617 allocs/op +BenchmarkToXXXName/ToCommandName-4 1276322 27903 ns/op 9785 B/op 617 allocs/op +BenchmarkToXXXName/ToHumanNameLower-4 895334 40354 ns/op 10472 B/op 731 allocs/op +BenchmarkToXXXName/ToHumanNameTitle-4 882441 40678 ns/op 10566 B/op 749 allocs/op +``` + +### Benchmarks after PR #79 + +~ x10 performance improvement and ~ /100 memory allocations. + +``` +goos: linux +goarch: amd64 +pkg: github.com/go-openapi/swag +cpu: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz +BenchmarkToXXXName/ToGoName-4 9595830 3991 ns/op 42 B/op 5 allocs/op +BenchmarkToXXXName/ToVarName-4 9194276 3984 ns/op 62 B/op 7 allocs/op +BenchmarkToXXXName/ToFileName-4 17002711 2123 ns/op 147 B/op 7 allocs/op +BenchmarkToXXXName/ToCommandName-4 16772926 2111 ns/op 147 B/op 7 allocs/op +BenchmarkToXXXName/ToHumanNameLower-4 9788331 3749 ns/op 92 B/op 6 allocs/op +BenchmarkToXXXName/ToHumanNameTitle-4 9188260 3941 ns/op 104 B/op 6 allocs/op +``` + +``` +goos: linux +goarch: amd64 +pkg: github.com/go-openapi/swag +cpu: AMD Ryzen 7 5800X 8-Core Processor +BenchmarkToXXXName/ToGoName-16 18527378 1972 ns/op 42 B/op 5 allocs/op +BenchmarkToXXXName/ToVarName-16 15552692 2093 ns/op 62 B/op 7 allocs/op +BenchmarkToXXXName/ToFileName-16 32161176 1117 ns/op 147 B/op 7 allocs/op +BenchmarkToXXXName/ToCommandName-16 32256634 1137 ns/op 147 B/op 7 allocs/op +BenchmarkToXXXName/ToHumanNameLower-16 18599661 1946 ns/op 92 B/op 6 allocs/op +BenchmarkToXXXName/ToHumanNameTitle-16 17581353 2054 ns/op 105 B/op 6 allocs/op +``` diff --git a/vendor/github.com/go-openapi/swag/README.md b/vendor/github.com/go-openapi/swag/README.md index 217f6fa5054..a7292229980 100644 --- a/vendor/github.com/go-openapi/swag/README.md +++ b/vendor/github.com/go-openapi/swag/README.md @@ -1,7 +1,8 @@ -# Swag [![Build Status](https://travis-ci.org/go-openapi/swag.svg?branch=master)](https://travis-ci.org/go-openapi/swag) [![codecov](https://codecov.io/gh/go-openapi/swag/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/swag) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) +# Swag [![Build Status](https://github.com/go-openapi/swag/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/swag/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/swag/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/swag) +[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE) -[![GoDoc](https://godoc.org/github.com/go-openapi/swag?status.svg)](http://godoc.org/github.com/go-openapi/swag) +[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/swag.svg)](https://pkg.go.dev/github.com/go-openapi/swag) [![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/swag)](https://goreportcard.com/report/github.com/go-openapi/swag) Contains a bunch of helper functions for go-openapi and go-swagger projects. @@ -18,4 +19,5 @@ You may also use it standalone for your projects. This repo has only few dependencies outside of the standard library: -* YAML utilities depend on gopkg.in/yaml.v2 +* YAML utilities depend on `gopkg.in/yaml.v3` +* `github.com/mailru/easyjson v0.7.7` diff --git a/vendor/github.com/go-openapi/swag/initialism_index.go b/vendor/github.com/go-openapi/swag/initialism_index.go new file mode 100644 index 00000000000..20a359bb60a --- /dev/null +++ b/vendor/github.com/go-openapi/swag/initialism_index.go @@ -0,0 +1,202 @@ +// Copyright 2015 go-swagger maintainers +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package swag + +import ( + "sort" + "strings" + "sync" +) + +var ( + // commonInitialisms are common acronyms that are kept as whole uppercased words. + commonInitialisms *indexOfInitialisms + + // initialisms is a slice of sorted initialisms + initialisms []string + + // a copy of initialisms pre-baked as []rune + initialismsRunes [][]rune + initialismsUpperCased [][]rune + + isInitialism func(string) bool + + maxAllocMatches int +) + +func init() { + // Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769 + configuredInitialisms := map[string]bool{ + "ACL": true, + "API": true, + "ASCII": true, + "CPU": true, + "CSS": true, + "DNS": true, + "EOF": true, + "GUID": true, + "HTML": true, + "HTTPS": true, + "HTTP": true, + "ID": true, + "IP": true, + "IPv4": true, + "IPv6": true, + "JSON": true, + "LHS": true, + "OAI": true, + "QPS": true, + "RAM": true, + "RHS": true, + "RPC": true, + "SLA": true, + "SMTP": true, + "SQL": true, + "SSH": true, + "TCP": true, + "TLS": true, + "TTL": true, + "UDP": true, + "UI": true, + "UID": true, + "UUID": true, + "URI": true, + "URL": true, + "UTF8": true, + "VM": true, + "XML": true, + "XMPP": true, + "XSRF": true, + "XSS": true, + } + + // a thread-safe index of initialisms + commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms) + initialisms = commonInitialisms.sorted() + initialismsRunes = asRunes(initialisms) + initialismsUpperCased = asUpperCased(initialisms) + maxAllocMatches = maxAllocHeuristic(initialismsRunes) + + // a test function + isInitialism = commonInitialisms.isInitialism +} + +func asRunes(in []string) [][]rune { + out := make([][]rune, len(in)) + for i, initialism := range in { + out[i] = []rune(initialism) + } + + return out +} + +func asUpperCased(in []string) [][]rune { + out := make([][]rune, len(in)) + + for i, initialism := range in { + out[i] = []rune(upper(trim(initialism))) + } + + return out +} + +func maxAllocHeuristic(in [][]rune) int { + heuristic := make(map[rune]int) + for _, initialism := range in { + heuristic[initialism[0]]++ + } + + var maxAlloc int + for _, val := range heuristic { + if val > maxAlloc { + maxAlloc = val + } + } + + return maxAlloc +} + +// AddInitialisms add additional initialisms +func AddInitialisms(words ...string) { + for _, word := range words { + // commonInitialisms[upper(word)] = true + commonInitialisms.add(upper(word)) + } + // sort again + initialisms = commonInitialisms.sorted() + initialismsRunes = asRunes(initialisms) + initialismsUpperCased = asUpperCased(initialisms) +} + +// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms. +// Since go1.9, this may be implemented with sync.Map. +type indexOfInitialisms struct { + sortMutex *sync.Mutex + index *sync.Map +} + +func newIndexOfInitialisms() *indexOfInitialisms { + return &indexOfInitialisms{ + sortMutex: new(sync.Mutex), + index: new(sync.Map), + } +} + +func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms { + m.sortMutex.Lock() + defer m.sortMutex.Unlock() + for k, v := range initial { + m.index.Store(k, v) + } + return m +} + +func (m *indexOfInitialisms) isInitialism(key string) bool { + _, ok := m.index.Load(key) + return ok +} + +func (m *indexOfInitialisms) add(key string) *indexOfInitialisms { + m.index.Store(key, true) + return m +} + +func (m *indexOfInitialisms) sorted() (result []string) { + m.sortMutex.Lock() + defer m.sortMutex.Unlock() + m.index.Range(func(key, _ interface{}) bool { + k := key.(string) + result = append(result, k) + return true + }) + sort.Sort(sort.Reverse(byInitialism(result))) + return +} + +type byInitialism []string + +func (s byInitialism) Len() int { + return len(s) +} +func (s byInitialism) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} +func (s byInitialism) Less(i, j int) bool { + if len(s[i]) != len(s[j]) { + return len(s[i]) < len(s[j]) + } + + return strings.Compare(s[i], s[j]) > 0 +} diff --git a/vendor/github.com/go-openapi/swag/loading.go b/vendor/github.com/go-openapi/swag/loading.go index 00038c3773c..783442fddf6 100644 --- a/vendor/github.com/go-openapi/swag/loading.go +++ b/vendor/github.com/go-openapi/swag/loading.go @@ -21,6 +21,7 @@ import ( "net/http" "net/url" "os" + "path" "path/filepath" "runtime" "strings" @@ -40,43 +41,97 @@ var LoadHTTPBasicAuthPassword = "" var LoadHTTPCustomHeaders = map[string]string{} // LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in -func LoadFromFileOrHTTP(path string) ([]byte, error) { - return LoadStrategy(path, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path) +func LoadFromFileOrHTTP(pth string) ([]byte, error) { + return LoadStrategy(pth, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(pth) } // LoadFromFileOrHTTPWithTimeout loads the bytes from a file or a remote http server based on the path passed in // timeout arg allows for per request overriding of the request timeout -func LoadFromFileOrHTTPWithTimeout(path string, timeout time.Duration) ([]byte, error) { - return LoadStrategy(path, os.ReadFile, loadHTTPBytes(timeout))(path) +func LoadFromFileOrHTTPWithTimeout(pth string, timeout time.Duration) ([]byte, error) { + return LoadStrategy(pth, os.ReadFile, loadHTTPBytes(timeout))(pth) } -// LoadStrategy returns a loader function for a given path or uri -func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func(string) ([]byte, error) { - if strings.HasPrefix(path, "http") { +// LoadStrategy returns a loader function for a given path or URI. +// +// The load strategy returns the remote load for any path starting with `http`. +// So this works for any URI with a scheme `http` or `https`. +// +// The fallback strategy is to call the local loader. +// +// The local loader takes a local file system path (absolute or relative) as argument, +// or alternatively a `file://...` URI, **without host** (see also below for windows). +// +// There are a few liberalities, initially intended to be tolerant regarding the URI syntax, +// especially on windows. +// +// Before the local loader is called, the given path is transformed: +// - percent-encoded characters are unescaped +// - simple paths (e.g. `./folder/file`) are passed as-is +// - on windows, occurrences of `/` are replaced by `\`, so providing a relative path such a `folder/file` works too. +// +// For paths provided as URIs with the "file" scheme, please note that: +// - `file://` is simply stripped. +// This means that the host part of the URI is not parsed at all. +// For example, `file:///folder/file" becomes "/folder/file`, +// but `file://localhost/folder/file` becomes `localhost/folder/file` on unix systems. +// Similarly, `file://./folder/file` yields `./folder/file`. +// - on windows, `file://...` can take a host so as to specify an UNC share location. +// +// Reminder about windows-specifics: +// - `file://host/folder/file` becomes an UNC path like `\\host\folder\file` (no port specification is supported) +// - `file:///c:/folder/file` becomes `C:\folder\file` +// - `file://c:/folder/file` is tolerated (without leading `/`) and becomes `c:\folder\file` +func LoadStrategy(pth string, local, remote func(string) ([]byte, error)) func(string) ([]byte, error) { + if strings.HasPrefix(pth, "http") { return remote } - return func(pth string) ([]byte, error) { - upth, err := pathUnescape(pth) + + return func(p string) ([]byte, error) { + upth, err := url.PathUnescape(p) if err != nil { return nil, err } - if strings.HasPrefix(pth, `file://`) { - if runtime.GOOS == "windows" { - // support for canonical file URIs on windows. - // Zero tolerance here for dodgy URIs. - u, _ := url.Parse(upth) - if u.Host != "" { - // assume UNC name (volume share) - // file://host/share/folder\... ==> \\host\share\path\folder - // NOTE: UNC port not yet supported - upth = strings.Join([]string{`\`, u.Host, u.Path}, `\`) - } else { - // file:///c:/folder/... ==> just remove the leading slash - upth = strings.TrimPrefix(upth, `file:///`) - } - } else { - upth = strings.TrimPrefix(upth, `file://`) + if !strings.HasPrefix(p, `file://`) { + // regular file path provided: just normalize slashes + return local(filepath.FromSlash(upth)) + } + + if runtime.GOOS != "windows" { + // crude processing: this leaves full URIs with a host with a (mostly) unexpected result + upth = strings.TrimPrefix(upth, `file://`) + + return local(filepath.FromSlash(upth)) + } + + // windows-only pre-processing of file://... URIs + + // support for canonical file URIs on windows. + u, err := url.Parse(filepath.ToSlash(upth)) + if err != nil { + return nil, err + } + + if u.Host != "" { + // assume UNC name (volume share) + // NOTE: UNC port not yet supported + + // when the "host" segment is a drive letter: + // file://C:/folder/... => C:\folder + upth = path.Clean(strings.Join([]string{u.Host, u.Path}, `/`)) + if !strings.HasSuffix(u.Host, ":") && u.Host[0] != '.' { + // tolerance: if we have a leading dot, this can't be a host + // file://host/share/folder\... ==> \\host\share\path\folder + upth = "//" + upth + } + } else { + // no host, let's figure out if this is a drive letter + upth = strings.TrimPrefix(upth, `file://`) + first, _, _ := strings.Cut(strings.TrimPrefix(u.Path, "/"), "/") + if strings.HasSuffix(first, ":") { + // drive letter in the first segment: + // file:///c:/folder/... ==> strip the leading slash + upth = strings.TrimPrefix(upth, `/`) } } diff --git a/vendor/github.com/go-openapi/swag/name_lexem.go b/vendor/github.com/go-openapi/swag/name_lexem.go index aa7f6a9bb8e..8bb64ac32f9 100644 --- a/vendor/github.com/go-openapi/swag/name_lexem.go +++ b/vendor/github.com/go-openapi/swag/name_lexem.go @@ -14,74 +14,80 @@ package swag -import "unicode" +import ( + "unicode" + "unicode/utf8" +) type ( - nameLexem interface { - GetUnsafeGoName() string - GetOriginal() string - IsInitialism() bool - } + lexemKind uint8 - initialismNameLexem struct { + nameLexem struct { original string matchedInitialism string + kind lexemKind } +) - casualNameLexem struct { - original string - } +const ( + lexemKindCasualName lexemKind = iota + lexemKindInitialismName ) -func newInitialismNameLexem(original, matchedInitialism string) *initialismNameLexem { - return &initialismNameLexem{ +func newInitialismNameLexem(original, matchedInitialism string) nameLexem { + return nameLexem{ + kind: lexemKindInitialismName, original: original, matchedInitialism: matchedInitialism, } } -func newCasualNameLexem(original string) *casualNameLexem { - return &casualNameLexem{ +func newCasualNameLexem(original string) nameLexem { + return nameLexem{ + kind: lexemKindCasualName, original: original, } } -func (l *initialismNameLexem) GetUnsafeGoName() string { - return l.matchedInitialism -} +func (l nameLexem) GetUnsafeGoName() string { + if l.kind == lexemKindInitialismName { + return l.matchedInitialism + } + + var ( + first rune + rest string + ) -func (l *casualNameLexem) GetUnsafeGoName() string { - var first rune - var rest string for i, orig := range l.original { if i == 0 { first = orig continue } + if i > 0 { rest = l.original[i:] break } } + if len(l.original) > 1 { - return string(unicode.ToUpper(first)) + lower(rest) + b := poolOfBuffers.BorrowBuffer(utf8.UTFMax + len(rest)) + defer func() { + poolOfBuffers.RedeemBuffer(b) + }() + b.WriteRune(unicode.ToUpper(first)) + b.WriteString(lower(rest)) + return b.String() } return l.original } -func (l *initialismNameLexem) GetOriginal() string { +func (l nameLexem) GetOriginal() string { return l.original } -func (l *casualNameLexem) GetOriginal() string { - return l.original -} - -func (l *initialismNameLexem) IsInitialism() bool { - return true -} - -func (l *casualNameLexem) IsInitialism() bool { - return false +func (l nameLexem) IsInitialism() bool { + return l.kind == lexemKindInitialismName } diff --git a/vendor/github.com/go-openapi/swag/post_go19.go b/vendor/github.com/go-openapi/swag/post_go19.go deleted file mode 100644 index 7c7da9c0880..00000000000 --- a/vendor/github.com/go-openapi/swag/post_go19.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build go1.9 -// +build go1.9 - -package swag - -import ( - "sort" - "sync" -) - -// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms. -// Since go1.9, this may be implemented with sync.Map. -type indexOfInitialisms struct { - sortMutex *sync.Mutex - index *sync.Map -} - -func newIndexOfInitialisms() *indexOfInitialisms { - return &indexOfInitialisms{ - sortMutex: new(sync.Mutex), - index: new(sync.Map), - } -} - -func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms { - m.sortMutex.Lock() - defer m.sortMutex.Unlock() - for k, v := range initial { - m.index.Store(k, v) - } - return m -} - -func (m *indexOfInitialisms) isInitialism(key string) bool { - _, ok := m.index.Load(key) - return ok -} - -func (m *indexOfInitialisms) add(key string) *indexOfInitialisms { - m.index.Store(key, true) - return m -} - -func (m *indexOfInitialisms) sorted() (result []string) { - m.sortMutex.Lock() - defer m.sortMutex.Unlock() - m.index.Range(func(key, value interface{}) bool { - k := key.(string) - result = append(result, k) - return true - }) - sort.Sort(sort.Reverse(byInitialism(result))) - return -} diff --git a/vendor/github.com/go-openapi/swag/pre_go19.go b/vendor/github.com/go-openapi/swag/pre_go19.go deleted file mode 100644 index 0565db377be..00000000000 --- a/vendor/github.com/go-openapi/swag/pre_go19.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !go1.9 -// +build !go1.9 - -package swag - -import ( - "sort" - "sync" -) - -// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms. -// Before go1.9, this may be implemented with a mutex on the map. -type indexOfInitialisms struct { - getMutex *sync.Mutex - index map[string]bool -} - -func newIndexOfInitialisms() *indexOfInitialisms { - return &indexOfInitialisms{ - getMutex: new(sync.Mutex), - index: make(map[string]bool, 50), - } -} - -func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms { - m.getMutex.Lock() - defer m.getMutex.Unlock() - for k, v := range initial { - m.index[k] = v - } - return m -} - -func (m *indexOfInitialisms) isInitialism(key string) bool { - m.getMutex.Lock() - defer m.getMutex.Unlock() - _, ok := m.index[key] - return ok -} - -func (m *indexOfInitialisms) add(key string) *indexOfInitialisms { - m.getMutex.Lock() - defer m.getMutex.Unlock() - m.index[key] = true - return m -} - -func (m *indexOfInitialisms) sorted() (result []string) { - m.getMutex.Lock() - defer m.getMutex.Unlock() - for k := range m.index { - result = append(result, k) - } - sort.Sort(sort.Reverse(byInitialism(result))) - return -} diff --git a/vendor/github.com/go-openapi/swag/split.go b/vendor/github.com/go-openapi/swag/split.go index a1825fb7dc9..274727a866c 100644 --- a/vendor/github.com/go-openapi/swag/split.go +++ b/vendor/github.com/go-openapi/swag/split.go @@ -15,124 +15,269 @@ package swag import ( + "bytes" + "sync" "unicode" + "unicode/utf8" ) -var nameReplaceTable = map[rune]string{ - '@': "At ", - '&': "And ", - '|': "Pipe ", - '$': "Dollar ", - '!': "Bang ", - '-': "", - '_': "", -} - type ( splitter struct { - postSplitInitialismCheck bool initialisms []string + initialismsRunes [][]rune + initialismsUpperCased [][]rune // initialisms cached in their trimmed, upper-cased version + postSplitInitialismCheck bool + } + + splitterOption func(*splitter) + + initialismMatch struct { + body []rune + start, end int + complete bool + } + initialismMatches []initialismMatch +) + +type ( + // memory pools of temporary objects. + // + // These are used to recycle temporarily allocated objects + // and relieve the GC from undue pressure. + + matchesPool struct { + *sync.Pool } - splitterOption func(*splitter) *splitter + buffersPool struct { + *sync.Pool + } + + lexemsPool struct { + *sync.Pool + } + + splittersPool struct { + *sync.Pool + } ) -// split calls the splitter; splitter provides more control and post options +var ( + // poolOfMatches holds temporary slices for recycling during the initialism match process + poolOfMatches = matchesPool{ + Pool: &sync.Pool{ + New: func() any { + s := make(initialismMatches, 0, maxAllocMatches) + + return &s + }, + }, + } + + poolOfBuffers = buffersPool{ + Pool: &sync.Pool{ + New: func() any { + return new(bytes.Buffer) + }, + }, + } + + poolOfLexems = lexemsPool{ + Pool: &sync.Pool{ + New: func() any { + s := make([]nameLexem, 0, maxAllocMatches) + + return &s + }, + }, + } + + poolOfSplitters = splittersPool{ + Pool: &sync.Pool{ + New: func() any { + s := newSplitter() + + return &s + }, + }, + } +) + +// nameReplaceTable finds a word representation for special characters. +func nameReplaceTable(r rune) (string, bool) { + switch r { + case '@': + return "At ", true + case '&': + return "And ", true + case '|': + return "Pipe ", true + case '$': + return "Dollar ", true + case '!': + return "Bang ", true + case '-': + return "", true + case '_': + return "", true + default: + return "", false + } +} + +// split calls the splitter. +// +// Use newSplitter for more control and options func split(str string) []string { - lexems := newSplitter().split(str) - result := make([]string, 0, len(lexems)) + s := poolOfSplitters.BorrowSplitter() + lexems := s.split(str) + result := make([]string, 0, len(*lexems)) - for _, lexem := range lexems { + for _, lexem := range *lexems { result = append(result, lexem.GetOriginal()) } + poolOfLexems.RedeemLexems(lexems) + poolOfSplitters.RedeemSplitter(s) return result } -func (s *splitter) split(str string) []nameLexem { - return s.toNameLexems(str) -} - -func newSplitter(options ...splitterOption) *splitter { - splitter := &splitter{ +func newSplitter(options ...splitterOption) splitter { + s := splitter{ postSplitInitialismCheck: false, initialisms: initialisms, + initialismsRunes: initialismsRunes, + initialismsUpperCased: initialismsUpperCased, } for _, option := range options { - splitter = option(splitter) + option(&s) } - return splitter + return s } // withPostSplitInitialismCheck allows to catch initialisms after main split process -func withPostSplitInitialismCheck(s *splitter) *splitter { +func withPostSplitInitialismCheck(s *splitter) { s.postSplitInitialismCheck = true +} + +func (p matchesPool) BorrowMatches() *initialismMatches { + s := p.Get().(*initialismMatches) + *s = (*s)[:0] // reset slice, keep allocated capacity + return s } -type ( - initialismMatch struct { - start, end int - body []rune - complete bool +func (p buffersPool) BorrowBuffer(size int) *bytes.Buffer { + s := p.Get().(*bytes.Buffer) + s.Reset() + + if s.Cap() < size { + s.Grow(size) } - initialismMatches []*initialismMatch -) -func (s *splitter) toNameLexems(name string) []nameLexem { + return s +} + +func (p lexemsPool) BorrowLexems() *[]nameLexem { + s := p.Get().(*[]nameLexem) + *s = (*s)[:0] // reset slice, keep allocated capacity + + return s +} + +func (p splittersPool) BorrowSplitter(options ...splitterOption) *splitter { + s := p.Get().(*splitter) + s.postSplitInitialismCheck = false // reset options + for _, apply := range options { + apply(s) + } + + return s +} + +func (p matchesPool) RedeemMatches(s *initialismMatches) { + p.Put(s) +} + +func (p buffersPool) RedeemBuffer(s *bytes.Buffer) { + p.Put(s) +} + +func (p lexemsPool) RedeemLexems(s *[]nameLexem) { + p.Put(s) +} + +func (p splittersPool) RedeemSplitter(s *splitter) { + p.Put(s) +} + +func (m initialismMatch) isZero() bool { + return m.start == 0 && m.end == 0 +} + +func (s splitter) split(name string) *[]nameLexem { nameRunes := []rune(name) matches := s.gatherInitialismMatches(nameRunes) + if matches == nil { + return poolOfLexems.BorrowLexems() + } + return s.mapMatchesToNameLexems(nameRunes, matches) } -func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches { - matches := make(initialismMatches, 0) +func (s splitter) gatherInitialismMatches(nameRunes []rune) *initialismMatches { + var matches *initialismMatches for currentRunePosition, currentRune := range nameRunes { - newMatches := make(initialismMatches, 0, len(matches)) + // recycle these allocations as we loop over runes + // with such recycling, only 2 slices should be allocated per call + // instead of o(n). + newMatches := poolOfMatches.BorrowMatches() // check current initialism matches - for _, match := range matches { - if keepCompleteMatch := match.complete; keepCompleteMatch { - newMatches = append(newMatches, match) - continue - } + if matches != nil { // skip first iteration + for _, match := range *matches { + if keepCompleteMatch := match.complete; keepCompleteMatch { + *newMatches = append(*newMatches, match) + continue + } - // drop failed match - currentMatchRune := match.body[currentRunePosition-match.start] - if !s.initialismRuneEqual(currentMatchRune, currentRune) { - continue - } + // drop failed match + currentMatchRune := match.body[currentRunePosition-match.start] + if currentMatchRune != currentRune { + continue + } - // try to complete ongoing match - if currentRunePosition-match.start == len(match.body)-1 { - // we are close; the next step is to check the symbol ahead - // if it is a small letter, then it is not the end of match - // but beginning of the next word - - if currentRunePosition < len(nameRunes)-1 { - nextRune := nameRunes[currentRunePosition+1] - if newWord := unicode.IsLower(nextRune); newWord { - // oh ok, it was the start of a new word - continue + // try to complete ongoing match + if currentRunePosition-match.start == len(match.body)-1 { + // we are close; the next step is to check the symbol ahead + // if it is a small letter, then it is not the end of match + // but beginning of the next word + + if currentRunePosition < len(nameRunes)-1 { + nextRune := nameRunes[currentRunePosition+1] + if newWord := unicode.IsLower(nextRune); newWord { + // oh ok, it was the start of a new word + continue + } } + + match.complete = true + match.end = currentRunePosition } - match.complete = true - match.end = currentRunePosition + *newMatches = append(*newMatches, match) } - - newMatches = append(newMatches, match) } // check for new initialism matches - for _, initialism := range s.initialisms { - initialismRunes := []rune(initialism) - if s.initialismRuneEqual(initialismRunes[0], currentRune) { - newMatches = append(newMatches, &initialismMatch{ + for i := range s.initialisms { + initialismRunes := s.initialismsRunes[i] + if initialismRunes[0] == currentRune { + *newMatches = append(*newMatches, initialismMatch{ start: currentRunePosition, body: initialismRunes, complete: false, @@ -140,24 +285,28 @@ func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches { } } + if matches != nil { + poolOfMatches.RedeemMatches(matches) + } matches = newMatches } + // up to the caller to redeem this last slice return matches } -func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMatches) []nameLexem { - nameLexems := make([]nameLexem, 0) +func (s splitter) mapMatchesToNameLexems(nameRunes []rune, matches *initialismMatches) *[]nameLexem { + nameLexems := poolOfLexems.BorrowLexems() - var lastAcceptedMatch *initialismMatch - for _, match := range matches { + var lastAcceptedMatch initialismMatch + for _, match := range *matches { if !match.complete { continue } - if firstMatch := lastAcceptedMatch == nil; firstMatch { - nameLexems = append(nameLexems, s.breakCasualString(nameRunes[:match.start])...) - nameLexems = append(nameLexems, s.breakInitialism(string(match.body))) + if firstMatch := lastAcceptedMatch.isZero(); firstMatch { + s.appendBrokenDownCasualString(nameLexems, nameRunes[:match.start]) + *nameLexems = append(*nameLexems, s.breakInitialism(string(match.body))) lastAcceptedMatch = match @@ -169,63 +318,66 @@ func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMa } middle := nameRunes[lastAcceptedMatch.end+1 : match.start] - nameLexems = append(nameLexems, s.breakCasualString(middle)...) - nameLexems = append(nameLexems, s.breakInitialism(string(match.body))) + s.appendBrokenDownCasualString(nameLexems, middle) + *nameLexems = append(*nameLexems, s.breakInitialism(string(match.body))) lastAcceptedMatch = match } // we have not found any accepted matches - if lastAcceptedMatch == nil { - return s.breakCasualString(nameRunes) - } - - if lastAcceptedMatch.end+1 != len(nameRunes) { + if lastAcceptedMatch.isZero() { + *nameLexems = (*nameLexems)[:0] + s.appendBrokenDownCasualString(nameLexems, nameRunes) + } else if lastAcceptedMatch.end+1 != len(nameRunes) { rest := nameRunes[lastAcceptedMatch.end+1:] - nameLexems = append(nameLexems, s.breakCasualString(rest)...) + s.appendBrokenDownCasualString(nameLexems, rest) } - return nameLexems -} + poolOfMatches.RedeemMatches(matches) -func (s *splitter) initialismRuneEqual(a, b rune) bool { - return a == b + return nameLexems } -func (s *splitter) breakInitialism(original string) nameLexem { +func (s splitter) breakInitialism(original string) nameLexem { return newInitialismNameLexem(original, original) } -func (s *splitter) breakCasualString(str []rune) []nameLexem { - segments := make([]nameLexem, 0) - currentSegment := "" +func (s splitter) appendBrokenDownCasualString(segments *[]nameLexem, str []rune) { + currentSegment := poolOfBuffers.BorrowBuffer(len(str)) // unlike strings.Builder, bytes.Buffer initial storage can reused + defer func() { + poolOfBuffers.RedeemBuffer(currentSegment) + }() addCasualNameLexem := func(original string) { - segments = append(segments, newCasualNameLexem(original)) + *segments = append(*segments, newCasualNameLexem(original)) } addInitialismNameLexem := func(original, match string) { - segments = append(segments, newInitialismNameLexem(original, match)) + *segments = append(*segments, newInitialismNameLexem(original, match)) } - addNameLexem := func(original string) { - if s.postSplitInitialismCheck { - for _, initialism := range s.initialisms { - if upper(initialism) == upper(original) { - addInitialismNameLexem(original, initialism) + var addNameLexem func(string) + if s.postSplitInitialismCheck { + addNameLexem = func(original string) { + for i := range s.initialisms { + if isEqualFoldIgnoreSpace(s.initialismsUpperCased[i], original) { + addInitialismNameLexem(original, s.initialisms[i]) + return } } - } - addCasualNameLexem(original) + addCasualNameLexem(original) + } + } else { + addNameLexem = addCasualNameLexem } - for _, rn := range string(str) { - if replace, found := nameReplaceTable[rn]; found { - if currentSegment != "" { - addNameLexem(currentSegment) - currentSegment = "" + for _, rn := range str { + if replace, found := nameReplaceTable(rn); found { + if currentSegment.Len() > 0 { + addNameLexem(currentSegment.String()) + currentSegment.Reset() } if replace != "" { @@ -236,27 +388,121 @@ func (s *splitter) breakCasualString(str []rune) []nameLexem { } if !unicode.In(rn, unicode.L, unicode.M, unicode.N, unicode.Pc) { - if currentSegment != "" { - addNameLexem(currentSegment) - currentSegment = "" + if currentSegment.Len() > 0 { + addNameLexem(currentSegment.String()) + currentSegment.Reset() } continue } if unicode.IsUpper(rn) { - if currentSegment != "" { - addNameLexem(currentSegment) + if currentSegment.Len() > 0 { + addNameLexem(currentSegment.String()) } - currentSegment = "" + currentSegment.Reset() } - currentSegment += string(rn) + currentSegment.WriteRune(rn) + } + + if currentSegment.Len() > 0 { + addNameLexem(currentSegment.String()) } +} + +// isEqualFoldIgnoreSpace is the same as strings.EqualFold, but +// it ignores leading and trailing blank spaces in the compared +// string. +// +// base is assumed to be composed of upper-cased runes, and be already +// trimmed. +// +// This code is heavily inspired from strings.EqualFold. +func isEqualFoldIgnoreSpace(base []rune, str string) bool { + var i, baseIndex int + // equivalent to b := []byte(str), but without data copy + b := hackStringBytes(str) + + for i < len(b) { + if c := b[i]; c < utf8.RuneSelf { + // fast path for ASCII + if c != ' ' && c != '\t' { + break + } + i++ + + continue + } + + // unicode case + r, size := utf8.DecodeRune(b[i:]) + if !unicode.IsSpace(r) { + break + } + i += size + } + + if i >= len(b) { + return len(base) == 0 + } + + for _, baseRune := range base { + if i >= len(b) { + break + } + + if c := b[i]; c < utf8.RuneSelf { + // single byte rune case (ASCII) + if baseRune >= utf8.RuneSelf { + return false + } + + baseChar := byte(baseRune) + if c != baseChar && + !('a' <= c && c <= 'z' && c-'a'+'A' == baseChar) { + return false + } + + baseIndex++ + i++ + + continue + } + + // unicode case + r, size := utf8.DecodeRune(b[i:]) + if unicode.ToUpper(r) != baseRune { + return false + } + baseIndex++ + i += size + } + + if baseIndex != len(base) { + return false + } + + // all passed: now we should only have blanks + for i < len(b) { + if c := b[i]; c < utf8.RuneSelf { + // fast path for ASCII + if c != ' ' && c != '\t' { + return false + } + i++ + + continue + } + + // unicode case + r, size := utf8.DecodeRune(b[i:]) + if !unicode.IsSpace(r) { + return false + } - if currentSegment != "" { - addNameLexem(currentSegment) + i += size } - return segments + return true } diff --git a/vendor/github.com/go-openapi/swag/string_bytes.go b/vendor/github.com/go-openapi/swag/string_bytes.go new file mode 100644 index 00000000000..90745d5ca9f --- /dev/null +++ b/vendor/github.com/go-openapi/swag/string_bytes.go @@ -0,0 +1,8 @@ +package swag + +import "unsafe" + +// hackStringBytes returns the (unsafe) underlying bytes slice of a string. +func hackStringBytes(str string) []byte { + return unsafe.Slice(unsafe.StringData(str), len(str)) +} diff --git a/vendor/github.com/go-openapi/swag/util.go b/vendor/github.com/go-openapi/swag/util.go index d971fbe34b4..5051401c49f 100644 --- a/vendor/github.com/go-openapi/swag/util.go +++ b/vendor/github.com/go-openapi/swag/util.go @@ -18,76 +18,25 @@ import ( "reflect" "strings" "unicode" + "unicode/utf8" ) -// commonInitialisms are common acronyms that are kept as whole uppercased words. -var commonInitialisms *indexOfInitialisms - -// initialisms is a slice of sorted initialisms -var initialisms []string - -var isInitialism func(string) bool - // GoNamePrefixFunc sets an optional rule to prefix go names // which do not start with a letter. // +// The prefix function is assumed to return a string that starts with an upper case letter. +// // e.g. to help convert "123" into "{prefix}123" // // The default is to prefix with "X" var GoNamePrefixFunc func(string) string -func init() { - // Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769 - var configuredInitialisms = map[string]bool{ - "ACL": true, - "API": true, - "ASCII": true, - "CPU": true, - "CSS": true, - "DNS": true, - "EOF": true, - "GUID": true, - "HTML": true, - "HTTPS": true, - "HTTP": true, - "ID": true, - "IP": true, - "IPv4": true, - "IPv6": true, - "JSON": true, - "LHS": true, - "OAI": true, - "QPS": true, - "RAM": true, - "RHS": true, - "RPC": true, - "SLA": true, - "SMTP": true, - "SQL": true, - "SSH": true, - "TCP": true, - "TLS": true, - "TTL": true, - "UDP": true, - "UI": true, - "UID": true, - "UUID": true, - "URI": true, - "URL": true, - "UTF8": true, - "VM": true, - "XML": true, - "XMPP": true, - "XSRF": true, - "XSS": true, +func prefixFunc(name, in string) string { + if GoNamePrefixFunc == nil { + return "X" + in } - // a thread-safe index of initialisms - commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms) - initialisms = commonInitialisms.sorted() - - // a test function - isInitialism = commonInitialisms.isInitialism + return GoNamePrefixFunc(name) + in } const ( @@ -156,25 +105,9 @@ func SplitByFormat(data, format string) []string { return result } -type byInitialism []string - -func (s byInitialism) Len() int { - return len(s) -} -func (s byInitialism) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} -func (s byInitialism) Less(i, j int) bool { - if len(s[i]) != len(s[j]) { - return len(s[i]) < len(s[j]) - } - - return strings.Compare(s[i], s[j]) > 0 -} - // Removes leading whitespaces func trim(str string) string { - return strings.Trim(str, " ") + return strings.TrimSpace(str) } // Shortcut to strings.ToUpper() @@ -188,15 +121,20 @@ func lower(str string) string { } // Camelize an uppercased word -func Camelize(word string) (camelized string) { +func Camelize(word string) string { + camelized := poolOfBuffers.BorrowBuffer(len(word)) + defer func() { + poolOfBuffers.RedeemBuffer(camelized) + }() + for pos, ru := range []rune(word) { if pos > 0 { - camelized += string(unicode.ToLower(ru)) + camelized.WriteRune(unicode.ToLower(ru)) } else { - camelized += string(unicode.ToUpper(ru)) + camelized.WriteRune(unicode.ToUpper(ru)) } } - return + return camelized.String() } // ToFileName lowercases and underscores a go type name @@ -224,33 +162,40 @@ func ToCommandName(name string) string { // ToHumanNameLower represents a code name as a human series of words func ToHumanNameLower(name string) string { - in := newSplitter(withPostSplitInitialismCheck).split(name) - out := make([]string, 0, len(in)) + s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck) + in := s.split(name) + poolOfSplitters.RedeemSplitter(s) + out := make([]string, 0, len(*in)) - for _, w := range in { + for _, w := range *in { if !w.IsInitialism() { out = append(out, lower(w.GetOriginal())) } else { - out = append(out, w.GetOriginal()) + out = append(out, trim(w.GetOriginal())) } } + poolOfLexems.RedeemLexems(in) return strings.Join(out, " ") } // ToHumanNameTitle represents a code name as a human series of words with the first letters titleized func ToHumanNameTitle(name string) string { - in := newSplitter(withPostSplitInitialismCheck).split(name) + s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck) + in := s.split(name) + poolOfSplitters.RedeemSplitter(s) - out := make([]string, 0, len(in)) - for _, w := range in { - original := w.GetOriginal() + out := make([]string, 0, len(*in)) + for _, w := range *in { + original := trim(w.GetOriginal()) if !w.IsInitialism() { out = append(out, Camelize(original)) } else { out = append(out, original) } } + poolOfLexems.RedeemLexems(in) + return strings.Join(out, " ") } @@ -264,7 +209,7 @@ func ToJSONName(name string) string { out = append(out, lower(w)) continue } - out = append(out, Camelize(w)) + out = append(out, Camelize(trim(w))) } return strings.Join(out, "") } @@ -283,35 +228,70 @@ func ToVarName(name string) string { // ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes func ToGoName(name string) string { - lexems := newSplitter(withPostSplitInitialismCheck).split(name) + s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck) + lexems := s.split(name) + poolOfSplitters.RedeemSplitter(s) + defer func() { + poolOfLexems.RedeemLexems(lexems) + }() + lexemes := *lexems + + if len(lexemes) == 0 { + return "" + } + + result := poolOfBuffers.BorrowBuffer(len(name)) + defer func() { + poolOfBuffers.RedeemBuffer(result) + }() + + // check if not starting with a letter, upper case + firstPart := lexemes[0].GetUnsafeGoName() + if lexemes[0].IsInitialism() { + firstPart = upper(firstPart) + } + + if c := firstPart[0]; c < utf8.RuneSelf { + // ASCII + switch { + case 'A' <= c && c <= 'Z': + result.WriteString(firstPart) + case 'a' <= c && c <= 'z': + result.WriteByte(c - 'a' + 'A') + result.WriteString(firstPart[1:]) + default: + result.WriteString(prefixFunc(name, firstPart)) + // NOTE: no longer check if prefixFunc returns a string that starts with uppercase: + // assume this is always the case + } + } else { + // unicode + firstRune, _ := utf8.DecodeRuneInString(firstPart) + switch { + case !unicode.IsLetter(firstRune): + result.WriteString(prefixFunc(name, firstPart)) + case !unicode.IsUpper(firstRune): + result.WriteString(prefixFunc(name, firstPart)) + /* + result.WriteRune(unicode.ToUpper(firstRune)) + result.WriteString(firstPart[offset:]) + */ + default: + result.WriteString(firstPart) + } + } - result := "" - for _, lexem := range lexems { + for _, lexem := range lexemes[1:] { goName := lexem.GetUnsafeGoName() // to support old behavior if lexem.IsInitialism() { goName = upper(goName) } - result += goName + result.WriteString(goName) } - if len(result) > 0 { - // Only prefix with X when the first character isn't an ascii letter - first := []rune(result)[0] - if !unicode.IsLetter(first) || (first > unicode.MaxASCII && !unicode.IsUpper(first)) { - if GoNamePrefixFunc == nil { - return "X" + result - } - result = GoNamePrefixFunc(name) + result - } - first = []rune(result)[0] - if unicode.IsLetter(first) && !unicode.IsUpper(first) { - result = string(append([]rune{unicode.ToUpper(first)}, []rune(result)[1:]...)) - } - } - - return result + return result.String() } // ContainsStrings searches a slice of strings for a case-sensitive match @@ -343,7 +323,7 @@ type zeroable interface { func IsZero(data interface{}) bool { v := reflect.ValueOf(data) // check for nil data - switch v.Kind() { + switch v.Kind() { //nolint:exhaustive case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: if v.IsNil() { return true @@ -356,7 +336,7 @@ func IsZero(data interface{}) bool { } // continue with slightly more complex reflection - switch v.Kind() { + switch v.Kind() { //nolint:exhaustive case reflect.String: return v.Len() == 0 case reflect.Bool: @@ -376,16 +356,6 @@ func IsZero(data interface{}) bool { } } -// AddInitialisms add additional initialisms -func AddInitialisms(words ...string) { - for _, word := range words { - // commonInitialisms[upper(word)] = true - commonInitialisms.add(upper(word)) - } - // sort again - initialisms = commonInitialisms.sorted() -} - // CommandLineOptionsGroup represents a group of user-defined command line options type CommandLineOptionsGroup struct { ShortDescription string diff --git a/vendor/github.com/go-openapi/swag/yaml.go b/vendor/github.com/go-openapi/swag/yaml.go index f09ee609f3b..f59e0259320 100644 --- a/vendor/github.com/go-openapi/swag/yaml.go +++ b/vendor/github.com/go-openapi/swag/yaml.go @@ -16,8 +16,11 @@ package swag import ( "encoding/json" + "errors" "fmt" "path/filepath" + "reflect" + "sort" "strconv" "github.com/mailru/easyjson/jlexer" @@ -48,7 +51,7 @@ func BytesToYAMLDoc(data []byte) (interface{}, error) { return nil, err } if document.Kind != yaml.DocumentNode || len(document.Content) != 1 || document.Content[0].Kind != yaml.MappingNode { - return nil, fmt.Errorf("only YAML documents that are objects are supported") + return nil, errors.New("only YAML documents that are objects are supported") } return &document, nil } @@ -147,7 +150,7 @@ func yamlScalar(node *yaml.Node) (interface{}, error) { case yamlTimestamp: return node.Value, nil case yamlNull: - return nil, nil + return nil, nil //nolint:nilnil default: return nil, fmt.Errorf("YAML tag %q is not supported", node.LongTag()) } @@ -245,7 +248,27 @@ func (s JSONMapSlice) MarshalYAML() (interface{}, error) { return yaml.Marshal(&n) } +func isNil(input interface{}) bool { + if input == nil { + return true + } + kind := reflect.TypeOf(input).Kind() + switch kind { //nolint:exhaustive + case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan: + return reflect.ValueOf(input).IsNil() + default: + return false + } +} + func json2yaml(item interface{}) (*yaml.Node, error) { + if isNil(item) { + return &yaml.Node{ + Kind: yaml.ScalarNode, + Value: "null", + }, nil + } + switch val := item.(type) { case JSONMapSlice: var n yaml.Node @@ -265,7 +288,14 @@ func json2yaml(item interface{}) (*yaml.Node, error) { case map[string]interface{}: var n yaml.Node n.Kind = yaml.MappingNode - for k, v := range val { + keys := make([]string, 0, len(val)) + for k := range val { + keys = append(keys, k) + } + sort.Strings(keys) + + for _, k := range keys { + v := val[k] childNode, err := json2yaml(v) if err != nil { return nil, err @@ -318,8 +348,9 @@ func json2yaml(item interface{}) (*yaml.Node, error) { Tag: yamlBoolScalar, Value: strconv.FormatBool(val), }, nil + default: + return nil, fmt.Errorf("unhandled type: %T", val) } - return nil, nil } // JSONMapItem represents the value of a key in a JSON object held by JSONMapSlice diff --git a/vendor/github.com/golang/mock/AUTHORS b/vendor/github.com/golang/mock/AUTHORS new file mode 100644 index 00000000000..660b8ccc8ae --- /dev/null +++ b/vendor/github.com/golang/mock/AUTHORS @@ -0,0 +1,12 @@ +# This is the official list of GoMock authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS files. +# See the latter for an explanation. + +# Names should be added to this file as +# Name or Organization +# The email address is not required for organizations. + +# Please keep the list sorted. + +Alex Reece +Google Inc. diff --git a/vendor/github.com/golang/mock/CONTRIBUTORS b/vendor/github.com/golang/mock/CONTRIBUTORS new file mode 100644 index 00000000000..def849cab1b --- /dev/null +++ b/vendor/github.com/golang/mock/CONTRIBUTORS @@ -0,0 +1,37 @@ +# This is the official list of people who can contribute (and typically +# have contributed) code to the gomock repository. +# The AUTHORS file lists the copyright holders; this file +# lists people. For example, Google employees are listed here +# but not in AUTHORS, because Google holds the copyright. +# +# The submission process automatically checks to make sure +# that people submitting code are listed in this file (by email address). +# +# Names should be added to this file only after verifying that +# the individual or the individual's organization has agreed to +# the appropriate Contributor License Agreement, found here: +# +# http://code.google.com/legal/individual-cla-v1.0.html +# http://code.google.com/legal/corporate-cla-v1.0.html +# +# The agreement for individuals can be filled out on the web. +# +# When adding J Random Contributor's name to this file, +# either J's name or J's organization's name should be +# added to the AUTHORS file, depending on whether the +# individual or corporate CLA was used. + +# Names should be added to this file like so: +# Name +# +# An entry with two email addresses specifies that the +# first address should be used in the submit logs and +# that the second address should be recognized as the +# same person when interacting with Rietveld. + +# Please keep the list sorted. + +Aaron Jacobs +Alex Reece +David Symonds +Ryan Barrett diff --git a/vendor/github.com/golang/mock/LICENSE b/vendor/github.com/golang/mock/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/vendor/github.com/golang/mock/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/golang/mock/gomock/call.go b/vendor/github.com/golang/mock/gomock/call.go new file mode 100644 index 00000000000..13c9f44b1ef --- /dev/null +++ b/vendor/github.com/golang/mock/gomock/call.go @@ -0,0 +1,445 @@ +// Copyright 2010 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gomock + +import ( + "fmt" + "reflect" + "strconv" + "strings" +) + +// Call represents an expected call to a mock. +type Call struct { + t TestHelper // for triggering test failures on invalid call setup + + receiver interface{} // the receiver of the method call + method string // the name of the method + methodType reflect.Type // the type of the method + args []Matcher // the args + origin string // file and line number of call setup + + preReqs []*Call // prerequisite calls + + // Expectations + minCalls, maxCalls int + + numCalls int // actual number made + + // actions are called when this Call is called. Each action gets the args and + // can set the return values by returning a non-nil slice. Actions run in the + // order they are created. + actions []func([]interface{}) []interface{} +} + +// newCall creates a *Call. It requires the method type in order to support +// unexported methods. +func newCall(t TestHelper, receiver interface{}, method string, methodType reflect.Type, args ...interface{}) *Call { + t.Helper() + + // TODO: check arity, types. + mArgs := make([]Matcher, len(args)) + for i, arg := range args { + if m, ok := arg.(Matcher); ok { + mArgs[i] = m + } else if arg == nil { + // Handle nil specially so that passing a nil interface value + // will match the typed nils of concrete args. + mArgs[i] = Nil() + } else { + mArgs[i] = Eq(arg) + } + } + + // callerInfo's skip should be updated if the number of calls between the user's test + // and this line changes, i.e. this code is wrapped in another anonymous function. + // 0 is us, 1 is RecordCallWithMethodType(), 2 is the generated recorder, and 3 is the user's test. + origin := callerInfo(3) + actions := []func([]interface{}) []interface{}{func([]interface{}) []interface{} { + // Synthesize the zero value for each of the return args' types. + rets := make([]interface{}, methodType.NumOut()) + for i := 0; i < methodType.NumOut(); i++ { + rets[i] = reflect.Zero(methodType.Out(i)).Interface() + } + return rets + }} + return &Call{t: t, receiver: receiver, method: method, methodType: methodType, + args: mArgs, origin: origin, minCalls: 1, maxCalls: 1, actions: actions} +} + +// AnyTimes allows the expectation to be called 0 or more times +func (c *Call) AnyTimes() *Call { + c.minCalls, c.maxCalls = 0, 1e8 // close enough to infinity + return c +} + +// MinTimes requires the call to occur at least n times. If AnyTimes or MaxTimes have not been called or if MaxTimes +// was previously called with 1, MinTimes also sets the maximum number of calls to infinity. +func (c *Call) MinTimes(n int) *Call { + c.minCalls = n + if c.maxCalls == 1 { + c.maxCalls = 1e8 + } + return c +} + +// MaxTimes limits the number of calls to n times. If AnyTimes or MinTimes have not been called or if MinTimes was +// previously called with 1, MaxTimes also sets the minimum number of calls to 0. +func (c *Call) MaxTimes(n int) *Call { + c.maxCalls = n + if c.minCalls == 1 { + c.minCalls = 0 + } + return c +} + +// DoAndReturn declares the action to run when the call is matched. +// The return values from this function are returned by the mocked function. +// It takes an interface{} argument to support n-arity functions. +func (c *Call) DoAndReturn(f interface{}) *Call { + // TODO: Check arity and types here, rather than dying badly elsewhere. + v := reflect.ValueOf(f) + + c.addAction(func(args []interface{}) []interface{} { + c.t.Helper() + vArgs := make([]reflect.Value, len(args)) + ft := v.Type() + if c.methodType.NumIn() != ft.NumIn() { + c.t.Fatalf("wrong number of arguments in DoAndReturn func for %T.%v: got %d, want %d [%s]", + c.receiver, c.method, ft.NumIn(), c.methodType.NumIn(), c.origin) + return nil + } + for i := 0; i < len(args); i++ { + if args[i] != nil { + vArgs[i] = reflect.ValueOf(args[i]) + } else { + // Use the zero value for the arg. + vArgs[i] = reflect.Zero(ft.In(i)) + } + } + vRets := v.Call(vArgs) + rets := make([]interface{}, len(vRets)) + for i, ret := range vRets { + rets[i] = ret.Interface() + } + return rets + }) + return c +} + +// Do declares the action to run when the call is matched. The function's +// return values are ignored to retain backward compatibility. To use the +// return values call DoAndReturn. +// It takes an interface{} argument to support n-arity functions. +func (c *Call) Do(f interface{}) *Call { + // TODO: Check arity and types here, rather than dying badly elsewhere. + v := reflect.ValueOf(f) + + c.addAction(func(args []interface{}) []interface{} { + c.t.Helper() + if c.methodType.NumIn() != v.Type().NumIn() { + c.t.Fatalf("wrong number of arguments in Do func for %T.%v: got %d, want %d [%s]", + c.receiver, c.method, v.Type().NumIn(), c.methodType.NumIn(), c.origin) + return nil + } + vArgs := make([]reflect.Value, len(args)) + ft := v.Type() + for i := 0; i < len(args); i++ { + if args[i] != nil { + vArgs[i] = reflect.ValueOf(args[i]) + } else { + // Use the zero value for the arg. + vArgs[i] = reflect.Zero(ft.In(i)) + } + } + v.Call(vArgs) + return nil + }) + return c +} + +// Return declares the values to be returned by the mocked function call. +func (c *Call) Return(rets ...interface{}) *Call { + c.t.Helper() + + mt := c.methodType + if len(rets) != mt.NumOut() { + c.t.Fatalf("wrong number of arguments to Return for %T.%v: got %d, want %d [%s]", + c.receiver, c.method, len(rets), mt.NumOut(), c.origin) + } + for i, ret := range rets { + if got, want := reflect.TypeOf(ret), mt.Out(i); got == want { + // Identical types; nothing to do. + } else if got == nil { + // Nil needs special handling. + switch want.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + // ok + default: + c.t.Fatalf("argument %d to Return for %T.%v is nil, but %v is not nillable [%s]", + i, c.receiver, c.method, want, c.origin) + } + } else if got.AssignableTo(want) { + // Assignable type relation. Make the assignment now so that the generated code + // can return the values with a type assertion. + v := reflect.New(want).Elem() + v.Set(reflect.ValueOf(ret)) + rets[i] = v.Interface() + } else { + c.t.Fatalf("wrong type of argument %d to Return for %T.%v: %v is not assignable to %v [%s]", + i, c.receiver, c.method, got, want, c.origin) + } + } + + c.addAction(func([]interface{}) []interface{} { + return rets + }) + + return c +} + +// Times declares the exact number of times a function call is expected to be executed. +func (c *Call) Times(n int) *Call { + c.minCalls, c.maxCalls = n, n + return c +} + +// SetArg declares an action that will set the nth argument's value, +// indirected through a pointer. Or, in the case of a slice, SetArg +// will copy value's elements into the nth argument. +func (c *Call) SetArg(n int, value interface{}) *Call { + c.t.Helper() + + mt := c.methodType + // TODO: This will break on variadic methods. + // We will need to check those at invocation time. + if n < 0 || n >= mt.NumIn() { + c.t.Fatalf("SetArg(%d, ...) called for a method with %d args [%s]", + n, mt.NumIn(), c.origin) + } + // Permit setting argument through an interface. + // In the interface case, we don't (nay, can't) check the type here. + at := mt.In(n) + switch at.Kind() { + case reflect.Ptr: + dt := at.Elem() + if vt := reflect.TypeOf(value); !vt.AssignableTo(dt) { + c.t.Fatalf("SetArg(%d, ...) argument is a %v, not assignable to %v [%s]", + n, vt, dt, c.origin) + } + case reflect.Interface: + // nothing to do + case reflect.Slice: + // nothing to do + default: + c.t.Fatalf("SetArg(%d, ...) referring to argument of non-pointer non-interface non-slice type %v [%s]", + n, at, c.origin) + } + + c.addAction(func(args []interface{}) []interface{} { + v := reflect.ValueOf(value) + switch reflect.TypeOf(args[n]).Kind() { + case reflect.Slice: + setSlice(args[n], v) + default: + reflect.ValueOf(args[n]).Elem().Set(v) + } + return nil + }) + return c +} + +// isPreReq returns true if other is a direct or indirect prerequisite to c. +func (c *Call) isPreReq(other *Call) bool { + for _, preReq := range c.preReqs { + if other == preReq || preReq.isPreReq(other) { + return true + } + } + return false +} + +// After declares that the call may only match after preReq has been exhausted. +func (c *Call) After(preReq *Call) *Call { + c.t.Helper() + + if c == preReq { + c.t.Fatalf("A call isn't allowed to be its own prerequisite") + } + if preReq.isPreReq(c) { + c.t.Fatalf("Loop in call order: %v is a prerequisite to %v (possibly indirectly).", c, preReq) + } + + c.preReqs = append(c.preReqs, preReq) + return c +} + +// Returns true if the minimum number of calls have been made. +func (c *Call) satisfied() bool { + return c.numCalls >= c.minCalls +} + +// Returns true if the maximum number of calls have been made. +func (c *Call) exhausted() bool { + return c.numCalls >= c.maxCalls +} + +func (c *Call) String() string { + args := make([]string, len(c.args)) + for i, arg := range c.args { + args[i] = arg.String() + } + arguments := strings.Join(args, ", ") + return fmt.Sprintf("%T.%v(%s) %s", c.receiver, c.method, arguments, c.origin) +} + +// Tests if the given call matches the expected call. +// If yes, returns nil. If no, returns error with message explaining why it does not match. +func (c *Call) matches(args []interface{}) error { + if !c.methodType.IsVariadic() { + if len(args) != len(c.args) { + return fmt.Errorf("expected call at %s has the wrong number of arguments. Got: %d, want: %d", + c.origin, len(args), len(c.args)) + } + + for i, m := range c.args { + if !m.Matches(args[i]) { + return fmt.Errorf( + "expected call at %s doesn't match the argument at index %d.\nGot: %v\nWant: %v", + c.origin, i, formatGottenArg(m, args[i]), m, + ) + } + } + } else { + if len(c.args) < c.methodType.NumIn()-1 { + return fmt.Errorf("expected call at %s has the wrong number of matchers. Got: %d, want: %d", + c.origin, len(c.args), c.methodType.NumIn()-1) + } + if len(c.args) != c.methodType.NumIn() && len(args) != len(c.args) { + return fmt.Errorf("expected call at %s has the wrong number of arguments. Got: %d, want: %d", + c.origin, len(args), len(c.args)) + } + if len(args) < len(c.args)-1 { + return fmt.Errorf("expected call at %s has the wrong number of arguments. Got: %d, want: greater than or equal to %d", + c.origin, len(args), len(c.args)-1) + } + + for i, m := range c.args { + if i < c.methodType.NumIn()-1 { + // Non-variadic args + if !m.Matches(args[i]) { + return fmt.Errorf("expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v", + c.origin, strconv.Itoa(i), formatGottenArg(m, args[i]), m) + } + continue + } + // The last arg has a possibility of a variadic argument, so let it branch + + // sample: Foo(a int, b int, c ...int) + if i < len(c.args) && i < len(args) { + if m.Matches(args[i]) { + // Got Foo(a, b, c) want Foo(matcherA, matcherB, gomock.Any()) + // Got Foo(a, b, c) want Foo(matcherA, matcherB, someSliceMatcher) + // Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC) + // Got Foo(a, b) want Foo(matcherA, matcherB) + // Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD) + continue + } + } + + // The number of actual args don't match the number of matchers, + // or the last matcher is a slice and the last arg is not. + // If this function still matches it is because the last matcher + // matches all the remaining arguments or the lack of any. + // Convert the remaining arguments, if any, into a slice of the + // expected type. + vArgsType := c.methodType.In(c.methodType.NumIn() - 1) + vArgs := reflect.MakeSlice(vArgsType, 0, len(args)-i) + for _, arg := range args[i:] { + vArgs = reflect.Append(vArgs, reflect.ValueOf(arg)) + } + if m.Matches(vArgs.Interface()) { + // Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, gomock.Any()) + // Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, someSliceMatcher) + // Got Foo(a, b) want Foo(matcherA, matcherB, gomock.Any()) + // Got Foo(a, b) want Foo(matcherA, matcherB, someEmptySliceMatcher) + break + } + // Wrong number of matchers or not match. Fail. + // Got Foo(a, b) want Foo(matcherA, matcherB, matcherC, matcherD) + // Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC, matcherD) + // Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD, matcherE) + // Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, matcherC, matcherD) + // Got Foo(a, b, c) want Foo(matcherA, matcherB) + + return fmt.Errorf("expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v", + c.origin, strconv.Itoa(i), formatGottenArg(m, args[i:]), c.args[i]) + } + } + + // Check that all prerequisite calls have been satisfied. + for _, preReqCall := range c.preReqs { + if !preReqCall.satisfied() { + return fmt.Errorf("expected call at %s doesn't have a prerequisite call satisfied:\n%v\nshould be called before:\n%v", + c.origin, preReqCall, c) + } + } + + // Check that the call is not exhausted. + if c.exhausted() { + return fmt.Errorf("expected call at %s has already been called the max number of times", c.origin) + } + + return nil +} + +// dropPrereqs tells the expected Call to not re-check prerequisite calls any +// longer, and to return its current set. +func (c *Call) dropPrereqs() (preReqs []*Call) { + preReqs = c.preReqs + c.preReqs = nil + return +} + +func (c *Call) call() []func([]interface{}) []interface{} { + c.numCalls++ + return c.actions +} + +// InOrder declares that the given calls should occur in order. +func InOrder(calls ...*Call) { + for i := 1; i < len(calls); i++ { + calls[i].After(calls[i-1]) + } +} + +func setSlice(arg interface{}, v reflect.Value) { + va := reflect.ValueOf(arg) + for i := 0; i < v.Len(); i++ { + va.Index(i).Set(v.Index(i)) + } +} + +func (c *Call) addAction(action func([]interface{}) []interface{}) { + c.actions = append(c.actions, action) +} + +func formatGottenArg(m Matcher, arg interface{}) string { + got := fmt.Sprintf("%v (%T)", arg, arg) + if gs, ok := m.(GotFormatter); ok { + got = gs.Got(arg) + } + return got +} diff --git a/vendor/github.com/golang/mock/gomock/callset.go b/vendor/github.com/golang/mock/gomock/callset.go new file mode 100644 index 00000000000..49dba787a40 --- /dev/null +++ b/vendor/github.com/golang/mock/gomock/callset.go @@ -0,0 +1,113 @@ +// Copyright 2011 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gomock + +import ( + "bytes" + "errors" + "fmt" +) + +// callSet represents a set of expected calls, indexed by receiver and method +// name. +type callSet struct { + // Calls that are still expected. + expected map[callSetKey][]*Call + // Calls that have been exhausted. + exhausted map[callSetKey][]*Call +} + +// callSetKey is the key in the maps in callSet +type callSetKey struct { + receiver interface{} + fname string +} + +func newCallSet() *callSet { + return &callSet{make(map[callSetKey][]*Call), make(map[callSetKey][]*Call)} +} + +// Add adds a new expected call. +func (cs callSet) Add(call *Call) { + key := callSetKey{call.receiver, call.method} + m := cs.expected + if call.exhausted() { + m = cs.exhausted + } + m[key] = append(m[key], call) +} + +// Remove removes an expected call. +func (cs callSet) Remove(call *Call) { + key := callSetKey{call.receiver, call.method} + calls := cs.expected[key] + for i, c := range calls { + if c == call { + // maintain order for remaining calls + cs.expected[key] = append(calls[:i], calls[i+1:]...) + cs.exhausted[key] = append(cs.exhausted[key], call) + break + } + } +} + +// FindMatch searches for a matching call. Returns error with explanation message if no call matched. +func (cs callSet) FindMatch(receiver interface{}, method string, args []interface{}) (*Call, error) { + key := callSetKey{receiver, method} + + // Search through the expected calls. + expected := cs.expected[key] + var callsErrors bytes.Buffer + for _, call := range expected { + err := call.matches(args) + if err != nil { + _, _ = fmt.Fprintf(&callsErrors, "\n%v", err) + } else { + return call, nil + } + } + + // If we haven't found a match then search through the exhausted calls so we + // get useful error messages. + exhausted := cs.exhausted[key] + for _, call := range exhausted { + if err := call.matches(args); err != nil { + _, _ = fmt.Fprintf(&callsErrors, "\n%v", err) + continue + } + _, _ = fmt.Fprintf( + &callsErrors, "all expected calls for method %q have been exhausted", method, + ) + } + + if len(expected)+len(exhausted) == 0 { + _, _ = fmt.Fprintf(&callsErrors, "there are no expected calls of the method %q for that receiver", method) + } + + return nil, errors.New(callsErrors.String()) +} + +// Failures returns the calls that are not satisfied. +func (cs callSet) Failures() []*Call { + failures := make([]*Call, 0, len(cs.expected)) + for _, calls := range cs.expected { + for _, call := range calls { + if !call.satisfied() { + failures = append(failures, call) + } + } + } + return failures +} diff --git a/vendor/github.com/golang/mock/gomock/controller.go b/vendor/github.com/golang/mock/gomock/controller.go new file mode 100644 index 00000000000..9b8bf38d3f3 --- /dev/null +++ b/vendor/github.com/golang/mock/gomock/controller.go @@ -0,0 +1,337 @@ +// Copyright 2010 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package gomock is a mock framework for Go. +// +// Standard usage: +// +// (1) Define an interface that you wish to mock. +// type MyInterface interface { +// SomeMethod(x int64, y string) +// } +// (2) Use mockgen to generate a mock from the interface. +// (3) Use the mock in a test: +// func TestMyThing(t *testing.T) { +// mockCtrl := gomock.NewController(t) +// defer mockCtrl.Finish() +// +// mockObj := something.NewMockMyInterface(mockCtrl) +// mockObj.EXPECT().SomeMethod(4, "blah") +// // pass mockObj to a real object and play with it. +// } +// +// By default, expected calls are not enforced to run in any particular order. +// Call order dependency can be enforced by use of InOrder and/or Call.After. +// Call.After can create more varied call order dependencies, but InOrder is +// often more convenient. +// +// The following examples create equivalent call order dependencies. +// +// Example of using Call.After to chain expected call order: +// +// firstCall := mockObj.EXPECT().SomeMethod(1, "first") +// secondCall := mockObj.EXPECT().SomeMethod(2, "second").After(firstCall) +// mockObj.EXPECT().SomeMethod(3, "third").After(secondCall) +// +// Example of using InOrder to declare expected call order: +// +// gomock.InOrder( +// mockObj.EXPECT().SomeMethod(1, "first"), +// mockObj.EXPECT().SomeMethod(2, "second"), +// mockObj.EXPECT().SomeMethod(3, "third"), +// ) +package gomock + +import ( + "context" + "fmt" + "reflect" + "runtime" + "sync" +) + +// A TestReporter is something that can be used to report test failures. It +// is satisfied by the standard library's *testing.T. +type TestReporter interface { + Errorf(format string, args ...interface{}) + Fatalf(format string, args ...interface{}) +} + +// TestHelper is a TestReporter that has the Helper method. It is satisfied +// by the standard library's *testing.T. +type TestHelper interface { + TestReporter + Helper() +} + +// cleanuper is used to check if TestHelper also has the `Cleanup` method. A +// common pattern is to pass in a `*testing.T` to +// `NewController(t TestReporter)`. In Go 1.14+, `*testing.T` has a cleanup +// method. This can be utilized to call `Finish()` so the caller of this library +// does not have to. +type cleanuper interface { + Cleanup(func()) +} + +// A Controller represents the top-level control of a mock ecosystem. It +// defines the scope and lifetime of mock objects, as well as their +// expectations. It is safe to call Controller's methods from multiple +// goroutines. Each test should create a new Controller and invoke Finish via +// defer. +// +// func TestFoo(t *testing.T) { +// ctrl := gomock.NewController(t) +// defer ctrl.Finish() +// // .. +// } +// +// func TestBar(t *testing.T) { +// t.Run("Sub-Test-1", st) { +// ctrl := gomock.NewController(st) +// defer ctrl.Finish() +// // .. +// }) +// t.Run("Sub-Test-2", st) { +// ctrl := gomock.NewController(st) +// defer ctrl.Finish() +// // .. +// }) +// }) +type Controller struct { + // T should only be called within a generated mock. It is not intended to + // be used in user code and may be changed in future versions. T is the + // TestReporter passed in when creating the Controller via NewController. + // If the TestReporter does not implement a TestHelper it will be wrapped + // with a nopTestHelper. + T TestHelper + mu sync.Mutex + expectedCalls *callSet + finished bool +} + +// NewController returns a new Controller. It is the preferred way to create a +// Controller. +// +// New in go1.14+, if you are passing a *testing.T into this function you no +// longer need to call ctrl.Finish() in your test methods. +func NewController(t TestReporter) *Controller { + h, ok := t.(TestHelper) + if !ok { + h = &nopTestHelper{t} + } + ctrl := &Controller{ + T: h, + expectedCalls: newCallSet(), + } + if c, ok := isCleanuper(ctrl.T); ok { + c.Cleanup(func() { + ctrl.T.Helper() + ctrl.finish(true, nil) + }) + } + + return ctrl +} + +type cancelReporter struct { + t TestHelper + cancel func() +} + +func (r *cancelReporter) Errorf(format string, args ...interface{}) { + r.t.Errorf(format, args...) +} +func (r *cancelReporter) Fatalf(format string, args ...interface{}) { + defer r.cancel() + r.t.Fatalf(format, args...) +} + +func (r *cancelReporter) Helper() { + r.t.Helper() +} + +// WithContext returns a new Controller and a Context, which is cancelled on any +// fatal failure. +func WithContext(ctx context.Context, t TestReporter) (*Controller, context.Context) { + h, ok := t.(TestHelper) + if !ok { + h = &nopTestHelper{t: t} + } + + ctx, cancel := context.WithCancel(ctx) + return NewController(&cancelReporter{t: h, cancel: cancel}), ctx +} + +type nopTestHelper struct { + t TestReporter +} + +func (h *nopTestHelper) Errorf(format string, args ...interface{}) { + h.t.Errorf(format, args...) +} +func (h *nopTestHelper) Fatalf(format string, args ...interface{}) { + h.t.Fatalf(format, args...) +} + +func (h nopTestHelper) Helper() {} + +// RecordCall is called by a mock. It should not be called by user code. +func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...interface{}) *Call { + ctrl.T.Helper() + + recv := reflect.ValueOf(receiver) + for i := 0; i < recv.Type().NumMethod(); i++ { + if recv.Type().Method(i).Name == method { + return ctrl.RecordCallWithMethodType(receiver, method, recv.Method(i).Type(), args...) + } + } + ctrl.T.Fatalf("gomock: failed finding method %s on %T", method, receiver) + panic("unreachable") +} + +// RecordCallWithMethodType is called by a mock. It should not be called by user code. +func (ctrl *Controller) RecordCallWithMethodType(receiver interface{}, method string, methodType reflect.Type, args ...interface{}) *Call { + ctrl.T.Helper() + + call := newCall(ctrl.T, receiver, method, methodType, args...) + + ctrl.mu.Lock() + defer ctrl.mu.Unlock() + ctrl.expectedCalls.Add(call) + + return call +} + +// Call is called by a mock. It should not be called by user code. +func (ctrl *Controller) Call(receiver interface{}, method string, args ...interface{}) []interface{} { + ctrl.T.Helper() + + // Nest this code so we can use defer to make sure the lock is released. + actions := func() []func([]interface{}) []interface{} { + ctrl.T.Helper() + ctrl.mu.Lock() + defer ctrl.mu.Unlock() + + expected, err := ctrl.expectedCalls.FindMatch(receiver, method, args) + if err != nil { + // callerInfo's skip should be updated if the number of calls between the user's test + // and this line changes, i.e. this code is wrapped in another anonymous function. + // 0 is us, 1 is controller.Call(), 2 is the generated mock, and 3 is the user's test. + origin := callerInfo(3) + ctrl.T.Fatalf("Unexpected call to %T.%v(%v) at %s because: %s", receiver, method, args, origin, err) + } + + // Two things happen here: + // * the matching call no longer needs to check prerequite calls, + // * and the prerequite calls are no longer expected, so remove them. + preReqCalls := expected.dropPrereqs() + for _, preReqCall := range preReqCalls { + ctrl.expectedCalls.Remove(preReqCall) + } + + actions := expected.call() + if expected.exhausted() { + ctrl.expectedCalls.Remove(expected) + } + return actions + }() + + var rets []interface{} + for _, action := range actions { + if r := action(args); r != nil { + rets = r + } + } + + return rets +} + +// Finish checks to see if all the methods that were expected to be called +// were called. It should be invoked for each Controller. It is not idempotent +// and therefore can only be invoked once. +// +// New in go1.14+, if you are passing a *testing.T into NewController function you no +// longer need to call ctrl.Finish() in your test methods. +func (ctrl *Controller) Finish() { + // If we're currently panicking, probably because this is a deferred call. + // This must be recovered in the deferred function. + err := recover() + ctrl.finish(false, err) +} + +func (ctrl *Controller) finish(cleanup bool, panicErr interface{}) { + ctrl.T.Helper() + + ctrl.mu.Lock() + defer ctrl.mu.Unlock() + + if ctrl.finished { + if _, ok := isCleanuper(ctrl.T); !ok { + ctrl.T.Fatalf("Controller.Finish was called more than once. It has to be called exactly once.") + } + return + } + ctrl.finished = true + + // Short-circuit, pass through the panic. + if panicErr != nil { + panic(panicErr) + } + + // Check that all remaining expected calls are satisfied. + failures := ctrl.expectedCalls.Failures() + for _, call := range failures { + ctrl.T.Errorf("missing call(s) to %v", call) + } + if len(failures) != 0 { + if !cleanup { + ctrl.T.Fatalf("aborting test due to missing call(s)") + return + } + ctrl.T.Errorf("aborting test due to missing call(s)") + } +} + +// callerInfo returns the file:line of the call site. skip is the number +// of stack frames to skip when reporting. 0 is callerInfo's call site. +func callerInfo(skip int) string { + if _, file, line, ok := runtime.Caller(skip + 1); ok { + return fmt.Sprintf("%s:%d", file, line) + } + return "unknown file" +} + +// isCleanuper checks it if t's base TestReporter has a Cleanup method. +func isCleanuper(t TestReporter) (cleanuper, bool) { + tr := unwrapTestReporter(t) + c, ok := tr.(cleanuper) + return c, ok +} + +// unwrapTestReporter unwraps TestReporter to the base implementation. +func unwrapTestReporter(t TestReporter) TestReporter { + tr := t + switch nt := t.(type) { + case *cancelReporter: + tr = nt.t + if h, check := tr.(*nopTestHelper); check { + tr = h.t + } + case *nopTestHelper: + tr = nt.t + default: + // not wrapped + } + return tr +} diff --git a/vendor/github.com/golang/mock/gomock/matchers.go b/vendor/github.com/golang/mock/gomock/matchers.go new file mode 100644 index 00000000000..6d5eff4fe4d --- /dev/null +++ b/vendor/github.com/golang/mock/gomock/matchers.go @@ -0,0 +1,346 @@ +// Copyright 2010 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gomock + +import ( + "fmt" + "reflect" + "strings" +) + +// A Matcher is a representation of a class of values. +// It is used to represent the valid or expected arguments to a mocked method. +type Matcher interface { + // Matches returns whether x is a match. + Matches(x interface{}) bool + + // String describes what the matcher matches. + String() string +} + +// WantFormatter modifies the given Matcher's String() method to the given +// Stringer. This allows for control on how the "Want" is formatted when +// printing . +func WantFormatter(s fmt.Stringer, m Matcher) Matcher { + type matcher interface { + Matches(x interface{}) bool + } + + return struct { + matcher + fmt.Stringer + }{ + matcher: m, + Stringer: s, + } +} + +// StringerFunc type is an adapter to allow the use of ordinary functions as +// a Stringer. If f is a function with the appropriate signature, +// StringerFunc(f) is a Stringer that calls f. +type StringerFunc func() string + +// String implements fmt.Stringer. +func (f StringerFunc) String() string { + return f() +} + +// GotFormatter is used to better print failure messages. If a matcher +// implements GotFormatter, it will use the result from Got when printing +// the failure message. +type GotFormatter interface { + // Got is invoked with the received value. The result is used when + // printing the failure message. + Got(got interface{}) string +} + +// GotFormatterFunc type is an adapter to allow the use of ordinary +// functions as a GotFormatter. If f is a function with the appropriate +// signature, GotFormatterFunc(f) is a GotFormatter that calls f. +type GotFormatterFunc func(got interface{}) string + +// Got implements GotFormatter. +func (f GotFormatterFunc) Got(got interface{}) string { + return f(got) +} + +// GotFormatterAdapter attaches a GotFormatter to a Matcher. +func GotFormatterAdapter(s GotFormatter, m Matcher) Matcher { + return struct { + GotFormatter + Matcher + }{ + GotFormatter: s, + Matcher: m, + } +} + +type anyMatcher struct{} + +func (anyMatcher) Matches(interface{}) bool { + return true +} + +func (anyMatcher) String() string { + return "is anything" +} + +type eqMatcher struct { + x interface{} +} + +func (e eqMatcher) Matches(x interface{}) bool { + // In case, some value is nil + if e.x == nil || x == nil { + return reflect.DeepEqual(e.x, x) + } + + // Check if types assignable and convert them to common type + x1Val := reflect.ValueOf(e.x) + x2Val := reflect.ValueOf(x) + + if x1Val.Type().AssignableTo(x2Val.Type()) { + x1ValConverted := x1Val.Convert(x2Val.Type()) + return reflect.DeepEqual(x1ValConverted.Interface(), x2Val.Interface()) + } + + return false +} + +func (e eqMatcher) String() string { + return fmt.Sprintf("is equal to %v (%T)", e.x, e.x) +} + +type nilMatcher struct{} + +func (nilMatcher) Matches(x interface{}) bool { + if x == nil { + return true + } + + v := reflect.ValueOf(x) + switch v.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, + reflect.Ptr, reflect.Slice: + return v.IsNil() + } + + return false +} + +func (nilMatcher) String() string { + return "is nil" +} + +type notMatcher struct { + m Matcher +} + +func (n notMatcher) Matches(x interface{}) bool { + return !n.m.Matches(x) +} + +func (n notMatcher) String() string { + return "not(" + n.m.String() + ")" +} + +type assignableToTypeOfMatcher struct { + targetType reflect.Type +} + +func (m assignableToTypeOfMatcher) Matches(x interface{}) bool { + return reflect.TypeOf(x).AssignableTo(m.targetType) +} + +func (m assignableToTypeOfMatcher) String() string { + return "is assignable to " + m.targetType.Name() +} + +type allMatcher struct { + matchers []Matcher +} + +func (am allMatcher) Matches(x interface{}) bool { + for _, m := range am.matchers { + if !m.Matches(x) { + return false + } + } + return true +} + +func (am allMatcher) String() string { + ss := make([]string, 0, len(am.matchers)) + for _, matcher := range am.matchers { + ss = append(ss, matcher.String()) + } + return strings.Join(ss, "; ") +} + +type lenMatcher struct { + i int +} + +func (m lenMatcher) Matches(x interface{}) bool { + v := reflect.ValueOf(x) + switch v.Kind() { + case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == m.i + default: + return false + } +} + +func (m lenMatcher) String() string { + return fmt.Sprintf("has length %d", m.i) +} + +type inAnyOrderMatcher struct { + x interface{} +} + +func (m inAnyOrderMatcher) Matches(x interface{}) bool { + given, ok := m.prepareValue(x) + if !ok { + return false + } + wanted, ok := m.prepareValue(m.x) + if !ok { + return false + } + + if given.Len() != wanted.Len() { + return false + } + + usedFromGiven := make([]bool, given.Len()) + foundFromWanted := make([]bool, wanted.Len()) + for i := 0; i < wanted.Len(); i++ { + wantedMatcher := Eq(wanted.Index(i).Interface()) + for j := 0; j < given.Len(); j++ { + if usedFromGiven[j] { + continue + } + if wantedMatcher.Matches(given.Index(j).Interface()) { + foundFromWanted[i] = true + usedFromGiven[j] = true + break + } + } + } + + missingFromWanted := 0 + for _, found := range foundFromWanted { + if !found { + missingFromWanted++ + } + } + extraInGiven := 0 + for _, used := range usedFromGiven { + if !used { + extraInGiven++ + } + } + + return extraInGiven == 0 && missingFromWanted == 0 +} + +func (m inAnyOrderMatcher) prepareValue(x interface{}) (reflect.Value, bool) { + xValue := reflect.ValueOf(x) + switch xValue.Kind() { + case reflect.Slice, reflect.Array: + return xValue, true + default: + return reflect.Value{}, false + } +} + +func (m inAnyOrderMatcher) String() string { + return fmt.Sprintf("has the same elements as %v", m.x) +} + +// Constructors + +// All returns a composite Matcher that returns true if and only all of the +// matchers return true. +func All(ms ...Matcher) Matcher { return allMatcher{ms} } + +// Any returns a matcher that always matches. +func Any() Matcher { return anyMatcher{} } + +// Eq returns a matcher that matches on equality. +// +// Example usage: +// +// Eq(5).Matches(5) // returns true +// Eq(5).Matches(4) // returns false +func Eq(x interface{}) Matcher { return eqMatcher{x} } + +// Len returns a matcher that matches on length. This matcher returns false if +// is compared to a type that is not an array, chan, map, slice, or string. +func Len(i int) Matcher { + return lenMatcher{i} +} + +// Nil returns a matcher that matches if the received value is nil. +// +// Example usage: +// +// var x *bytes.Buffer +// Nil().Matches(x) // returns true +// x = &bytes.Buffer{} +// Nil().Matches(x) // returns false +func Nil() Matcher { return nilMatcher{} } + +// Not reverses the results of its given child matcher. +// +// Example usage: +// +// Not(Eq(5)).Matches(4) // returns true +// Not(Eq(5)).Matches(5) // returns false +func Not(x interface{}) Matcher { + if m, ok := x.(Matcher); ok { + return notMatcher{m} + } + return notMatcher{Eq(x)} +} + +// AssignableToTypeOf is a Matcher that matches if the parameter to the mock +// function is assignable to the type of the parameter to this function. +// +// Example usage: +// +// var s fmt.Stringer = &bytes.Buffer{} +// AssignableToTypeOf(s).Matches(time.Second) // returns true +// AssignableToTypeOf(s).Matches(99) // returns false +// +// var ctx = reflect.TypeOf((*context.Context)(nil)).Elem() +// AssignableToTypeOf(ctx).Matches(context.Background()) // returns true +func AssignableToTypeOf(x interface{}) Matcher { + if xt, ok := x.(reflect.Type); ok { + return assignableToTypeOfMatcher{xt} + } + return assignableToTypeOfMatcher{reflect.TypeOf(x)} +} + +// InAnyOrder is a Matcher that returns true for collections of the same elements ignoring the order. +// +// Example usage: +// +// InAnyOrder([]int{1, 2, 3}).Matches([]int{1, 3, 2}) // returns true +// InAnyOrder([]int{1, 2, 3}).Matches([]int{1, 2}) // returns false +func InAnyOrder(x interface{}) Matcher { + return inAnyOrderMatcher{x} +} diff --git a/vendor/github.com/hashicorp/go-secure-stdlib/parseutil/LICENSE b/vendor/github.com/hashicorp/go-secure-stdlib/parseutil/LICENSE index e87a115e462..8d84ded1a56 100644 --- a/vendor/github.com/hashicorp/go-secure-stdlib/parseutil/LICENSE +++ b/vendor/github.com/hashicorp/go-secure-stdlib/parseutil/LICENSE @@ -1,3 +1,5 @@ +Copyright (c) 2020 HashiCorp, Inc. + Mozilla Public License, version 2.0 1. Definitions @@ -360,4 +362,3 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. - diff --git a/vendor/github.com/hashicorp/go-secure-stdlib/parseutil/parsepath.go b/vendor/github.com/hashicorp/go-secure-stdlib/parseutil/parsepath.go index 45e1497ca78..ec8123677d8 100644 --- a/vendor/github.com/hashicorp/go-secure-stdlib/parseutil/parsepath.go +++ b/vendor/github.com/hashicorp/go-secure-stdlib/parseutil/parsepath.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package parseutil import ( @@ -9,7 +12,10 @@ import ( "strings" ) -var ErrNotAUrl = errors.New("not a url") +var ( + ErrNotAUrl = errors.New("not a url") + ErrNotParsed = errors.New("not a parsed value") +) // ParsePath parses a URL with schemes file://, env://, or any other. Depending // on the scheme it will return specific types of data: @@ -18,7 +24,10 @@ var ErrNotAUrl = errors.New("not a url") // // * env:// will return a string with the env var's contents // -// * Anything else will return the string as it was +// * Anything else will return the string as it was. Functionally this means +// anything for which Go's `url.Parse` function does not throw an error. If you +// want to ensure that this function errors if a known scheme is not found, use +// MustParsePath. // // On error, we return the original string along with the error. The caller can // switch on errors.Is(err, ErrNotAUrl) to understand whether it was the parsing @@ -26,6 +35,16 @@ var ErrNotAUrl = errors.New("not a url") // useful to attempt to read a non-URL string from some resource, but where the // original input may simply be a valid string of that type. func ParsePath(path string) (string, error) { + return parsePath(path, false) +} + +// MustParsePath behaves like ParsePath but will return ErrNotAUrl if the value +// is not a URL with a scheme that can be parsed by this function. +func MustParsePath(path string) (string, error) { + return parsePath(path, true) +} + +func parsePath(path string, mustParse bool) (string, error) { path = strings.TrimSpace(path) parsed, err := url.Parse(path) if err != nil { @@ -40,7 +59,10 @@ func ParsePath(path string) (string, error) { return strings.TrimSpace(string(contents)), nil case "env": return strings.TrimSpace(os.Getenv(strings.TrimPrefix(path, "env://"))), nil + default: + if mustParse { + return "", ErrNotParsed + } + return path, nil } - - return path, nil } diff --git a/vendor/github.com/hashicorp/go-secure-stdlib/parseutil/parseutil.go b/vendor/github.com/hashicorp/go-secure-stdlib/parseutil/parseutil.go index e469499bdcd..eb3c0a50eae 100644 --- a/vendor/github.com/hashicorp/go-secure-stdlib/parseutil/parseutil.go +++ b/vendor/github.com/hashicorp/go-secure-stdlib/parseutil/parseutil.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package parseutil import ( diff --git a/vendor/github.com/hashicorp/go-sockaddr/LICENSE b/vendor/github.com/hashicorp/go-sockaddr/LICENSE index a612ad9813b..be467e386bb 100644 --- a/vendor/github.com/hashicorp/go-sockaddr/LICENSE +++ b/vendor/github.com/hashicorp/go-sockaddr/LICENSE @@ -1,3 +1,5 @@ +Copyright (c) 2016 HashiCorp, Inc. + Mozilla Public License Version 2.0 ================================== diff --git a/vendor/github.com/hashicorp/go-sockaddr/ifaddrs.go b/vendor/github.com/hashicorp/go-sockaddr/ifaddrs.go index 80f61bef680..8f51fc1b365 100644 --- a/vendor/github.com/hashicorp/go-sockaddr/ifaddrs.go +++ b/vendor/github.com/hashicorp/go-sockaddr/ifaddrs.go @@ -16,8 +16,10 @@ var ( // Centralize all regexps and regexp.Copy() where necessary. signRE *regexp.Regexp = regexp.MustCompile(`^[\s]*[+-]`) whitespaceRE *regexp.Regexp = regexp.MustCompile(`[\s]+`) - ifNameRE *regexp.Regexp = regexp.MustCompile(`^(?:Ethernet|Wireless LAN) adapter ([^:]+):`) - ipAddrRE *regexp.Regexp = regexp.MustCompile(`^ IPv[46] Address\. \. \. \. \. \. \. \. \. \. \. : ([^\s]+)`) + // These regular expressions enable the deprecated parseDefaultIfNameWindows + // and should be removed when those functions are. + ifNameRE *regexp.Regexp = regexp.MustCompile(`^(?:Ethernet|Wireless LAN) adapter ([^:]+):`) + ipAddrRE *regexp.Regexp = regexp.MustCompile(`^ IPv[46] Address\. \. \. \. \. \. \. \. \. \. \. : ([^\s]+)`) ) // IfAddrs is a slice of IfAddr @@ -301,7 +303,7 @@ func GetDefaultInterfaces() (IfAddrs, error) { // // ``` // $ sockaddr eval -r '{{GetAllInterfaces | include "type" "ip" | include "flags" "forwardable" | include "flags" "up" | sort "default,type,size" | include "RFC" "6890" }}' -/// ``` +// / ``` func GetPrivateInterfaces() (IfAddrs, error) { privateIfs, err := GetAllInterfaces() if err != nil { @@ -349,7 +351,7 @@ func GetPrivateInterfaces() (IfAddrs, error) { // // ``` // $ sockaddr eval -r '{{GetAllInterfaces | include "type" "ip" | include "flags" "forwardable" | include "flags" "up" | sort "default,type,size" | exclude "RFC" "6890" }}' -/// ``` +// / ``` func GetPublicInterfaces() (IfAddrs, error) { publicIfs, err := GetAllInterfaces() if err != nil { @@ -1214,7 +1216,7 @@ func parseDefaultIfNameFromIPCmd(routeOut string) (string, error) { // Android. func parseDefaultIfNameFromIPCmdAndroid(routeOut string) (string, error) { parsedLines := parseIfNameFromIPCmd(routeOut) - if (len(parsedLines) > 0) { + if len(parsedLines) > 0 { ifName := strings.TrimSpace(parsedLines[0][4]) return ifName, nil } @@ -1222,7 +1224,6 @@ func parseDefaultIfNameFromIPCmdAndroid(routeOut string) (string, error) { return "", errors.New("No default interface found") } - // parseIfNameFromIPCmd parses interfaces from ip(8) for // Linux. func parseIfNameFromIPCmd(routeOut string) [][]string { @@ -1241,6 +1242,10 @@ func parseIfNameFromIPCmd(routeOut string) [][]string { // parseDefaultIfNameWindows parses the default interface from `netstat -rn` and // `ipconfig` on Windows. +// +// This has been deprecated in favor of a Powershell-based solution because of +// issues with localized Windows versions, but is currently retained for backward +// compatibility func parseDefaultIfNameWindows(routeOut, ipconfigOut string) (string, error) { defaultIPAddr, err := parseDefaultIPAddrWindowsRoute(routeOut) if err != nil { @@ -1262,6 +1267,10 @@ func parseDefaultIfNameWindows(routeOut, ipconfigOut string) (string, error) { // IPv6 connected host, submit an issue on github.com/hashicorp/go-sockaddr with // the output from `netstat -rn`, `ipconfig`, and version of Windows to see IPv6 // support added. +// +// This has been deprecated in favor of a Powershell-based solution because of +// issues with localized Windows versions, but is currently retained for backward +// compatibility. func parseDefaultIPAddrWindowsRoute(routeOut string) (string, error) { lines := strings.Split(routeOut, "\n") re := whitespaceRE.Copy() @@ -1282,6 +1291,10 @@ func parseDefaultIPAddrWindowsRoute(routeOut string) (string, error) { // parseDefaultIfNameWindowsIPConfig parses the output of `ipconfig` to find the // interface name forwarding traffic to the default gateway. +// +// This has been deprecated in favor of a Powershell-based solution because of +// issues with localized Windows versions, but is currently retained for backward +// compatibility func parseDefaultIfNameWindowsIPConfig(defaultIPAddr, routeOut string) (string, error) { lines := strings.Split(routeOut, "\n") ifNameRe := ifNameRE.Copy() diff --git a/vendor/github.com/hashicorp/go-sockaddr/route_info.go b/vendor/github.com/hashicorp/go-sockaddr/route_info.go index 2a3ee1db9e8..601a2b5838c 100644 --- a/vendor/github.com/hashicorp/go-sockaddr/route_info.go +++ b/vendor/github.com/hashicorp/go-sockaddr/route_info.go @@ -1,5 +1,12 @@ package sockaddr +import "errors" + +var ( + ErrNoInterface = errors.New("No default interface found (unsupported platform)") + ErrNoRoute = errors.New("no route info found (unsupported platform)") +) + // RouteInterface specifies an interface for obtaining memoized route table and // network information from a given OS. type RouteInterface interface { @@ -9,6 +16,10 @@ type RouteInterface interface { GetDefaultInterfaceName() (string, error) } +type routeInfo struct { + cmds map[string][]string +} + // VisitCommands visits each command used by the platform-specific RouteInfo // implementation. func (ri routeInfo) VisitCommands(fn func(name string, cmd []string)) { diff --git a/vendor/github.com/hashicorp/go-sockaddr/route_info_bsd.go b/vendor/github.com/hashicorp/go-sockaddr/route_info_bsd.go index 705757abc7b..f5e548ac703 100644 --- a/vendor/github.com/hashicorp/go-sockaddr/route_info_bsd.go +++ b/vendor/github.com/hashicorp/go-sockaddr/route_info_bsd.go @@ -1,17 +1,14 @@ +//go:build darwin || dragonfly || freebsd || netbsd || openbsd // +build darwin dragonfly freebsd netbsd openbsd package sockaddr import "os/exec" -var cmds map[string][]string = map[string][]string{ +var cmds = map[string][]string{ "route": {"/sbin/route", "-n", "get", "default"}, } -type routeInfo struct { - cmds map[string][]string -} - // NewRouteInfo returns a BSD-specific implementation of the RouteInfo // interface. func NewRouteInfo() (routeInfo, error) { diff --git a/vendor/github.com/hashicorp/go-sockaddr/route_info_default.go b/vendor/github.com/hashicorp/go-sockaddr/route_info_default.go index d1b009f6538..6df864ba0fc 100644 --- a/vendor/github.com/hashicorp/go-sockaddr/route_info_default.go +++ b/vendor/github.com/hashicorp/go-sockaddr/route_info_default.go @@ -1,10 +1,19 @@ -// +build android nacl plan9 +//go:build android || nacl || plan9 || js +// +build android nacl plan9 js package sockaddr -import "errors" - // getDefaultIfName is the default interface function for unsupported platforms. func getDefaultIfName() (string, error) { - return "", errors.New("No default interface found (unsupported platform)") + return "", ErrNoInterface +} + +func NewRouteInfo() (routeInfo, error) { + return routeInfo{}, ErrNoRoute +} + +// GetDefaultInterfaceName returns the interface name attached to the default +// route on the default interface. +func (ri routeInfo) GetDefaultInterfaceName() (string, error) { + return "", ErrNoInterface } diff --git a/vendor/github.com/hashicorp/go-sockaddr/route_info_linux.go b/vendor/github.com/hashicorp/go-sockaddr/route_info_linux.go index b62ce6ecb21..cc5f68d0c83 100644 --- a/vendor/github.com/hashicorp/go-sockaddr/route_info_linux.go +++ b/vendor/github.com/hashicorp/go-sockaddr/route_info_linux.go @@ -1,3 +1,4 @@ +//go:build !android // +build !android package sockaddr @@ -7,10 +8,6 @@ import ( "os/exec" ) -type routeInfo struct { - cmds map[string][]string -} - // NewRouteInfo returns a Linux-specific implementation of the RouteInfo // interface. func NewRouteInfo() (routeInfo, error) { diff --git a/vendor/github.com/hashicorp/go-sockaddr/route_info_solaris.go b/vendor/github.com/hashicorp/go-sockaddr/route_info_solaris.go index ee8e7984d79..5843d58c2eb 100644 --- a/vendor/github.com/hashicorp/go-sockaddr/route_info_solaris.go +++ b/vendor/github.com/hashicorp/go-sockaddr/route_info_solaris.go @@ -9,10 +9,6 @@ var cmds map[string][]string = map[string][]string{ "route": {"/usr/sbin/route", "-n", "get", "default"}, } -type routeInfo struct { - cmds map[string][]string -} - // NewRouteInfo returns a BSD-specific implementation of the RouteInfo // interface. func NewRouteInfo() (routeInfo, error) { diff --git a/vendor/github.com/hashicorp/go-sockaddr/route_info_test_windows.go b/vendor/github.com/hashicorp/go-sockaddr/route_info_test_windows.go new file mode 100644 index 00000000000..a6eacdb2cf3 --- /dev/null +++ b/vendor/github.com/hashicorp/go-sockaddr/route_info_test_windows.go @@ -0,0 +1,25 @@ +package sockaddr + +import "testing" + +func Test_parseWindowsDefaultIfName_new_vs_old(t *testing.T) { + if !hasPowershell() { + t.Skip("this test requires powershell.") + return + } + ri, err := NewRouteInfo() + if err != nil { + t.Fatalf("bad: %v", err) + } + psVer, err1 := ri.GetDefaultInterfaceName() + legacyVer, err2 := ri.GetDefaultInterfaceNameLegacy() + if err1 != nil { + t.Errorf("err != nil for GetDefaultInterfaceName - %v", err1) + } + if err2 != nil { + t.Errorf("err != nil for GetDefaultInterfaceNameLegacy - %v", err2) + } + if psVer != legacyVer { + t.Errorf("got %s; want %s", psVer, legacyVer) + } +} diff --git a/vendor/github.com/hashicorp/go-sockaddr/route_info_windows.go b/vendor/github.com/hashicorp/go-sockaddr/route_info_windows.go index 3da972883e8..ed9bd0a3860 100644 --- a/vendor/github.com/hashicorp/go-sockaddr/route_info_windows.go +++ b/vendor/github.com/hashicorp/go-sockaddr/route_info_windows.go @@ -1,16 +1,18 @@ package sockaddr -import "os/exec" +import ( + "os/exec" + "strings" +) var cmds map[string][]string = map[string][]string{ + "defaultInterface": {"powershell", "Get-NetRoute -DestinationPrefix '0.0.0.0/0' | select -ExpandProperty InterfaceAlias"}, + // These commands enable GetDefaultInterfaceNameLegacy and should be removed + // when it is. "netstat": {"netstat", "-rn"}, "ipconfig": {"ipconfig"}, } -type routeInfo struct { - cmds map[string][]string -} - // NewRouteInfo returns a BSD-specific implementation of the RouteInfo // interface. func NewRouteInfo() (routeInfo, error) { @@ -22,6 +24,23 @@ func NewRouteInfo() (routeInfo, error) { // GetDefaultInterfaceName returns the interface name attached to the default // route on the default interface. func (ri routeInfo) GetDefaultInterfaceName() (string, error) { + if !hasPowershell() { + // No powershell, fallback to legacy method + return ri.GetDefaultInterfaceNameLegacy() + } + + ifNameOut, err := exec.Command(cmds["defaultInterface"][0], cmds["defaultInterface"][1:]...).Output() + if err != nil { + return "", err + } + + ifName := strings.TrimSpace(string(ifNameOut[:])) + return ifName, nil +} + +// GetDefaultInterfaceNameLegacy provides legacy behavior for GetDefaultInterfaceName +// on Windows machines without powershell. +func (ri routeInfo) GetDefaultInterfaceNameLegacy() (string, error) { ifNameOut, err := exec.Command(cmds["netstat"][0], cmds["netstat"][1:]...).Output() if err != nil { return "", err @@ -39,3 +58,8 @@ func (ri routeInfo) GetDefaultInterfaceName() (string, error) { return ifName, nil } + +func hasPowershell() bool { + _, err := exec.LookPath("powershell") + return (err != nil) +} diff --git a/vendor/github.com/hashicorp/go-sockaddr/unixsock.go b/vendor/github.com/hashicorp/go-sockaddr/unixsock.go index f3be3f67e77..17aed98adf0 100644 --- a/vendor/github.com/hashicorp/go-sockaddr/unixsock.go +++ b/vendor/github.com/hashicorp/go-sockaddr/unixsock.go @@ -27,6 +27,16 @@ func NewUnixSock(s string) (ret UnixSock, err error) { return ret, nil } +// Contains returns true if sa and us have the same path +func (us UnixSock) Contains(sa SockAddr) bool { + usb, ok := sa.(UnixSock) + if !ok { + return false + } + + return usb.path == us.path +} + // CmpAddress follows the Cmp() standard protocol and returns: // // - -1 If the receiver should sort first because its name lexically sorts before arg @@ -41,6 +51,9 @@ func (us UnixSock) CmpAddress(sa SockAddr) int { return strings.Compare(us.Path(), usb.Path()) } +// CmpRFC doesn't make sense for a Unix socket, so just return defer decision +func (us UnixSock) CmpRFC(rfcNum uint, sa SockAddr) int { return sortDeferDecision } + // DialPacketArgs returns the arguments required to be passed to net.DialUnix() // with the `unixgram` network type. func (us UnixSock) DialPacketArgs() (network, dialArgs string) { diff --git a/vendor/github.com/hashicorp/vault/api/auth/approle/LICENSE b/vendor/github.com/hashicorp/vault/api/auth/approle/LICENSE index 0ac557c3e18..503326e6260 100644 --- a/vendor/github.com/hashicorp/vault/api/auth/approle/LICENSE +++ b/vendor/github.com/hashicorp/vault/api/auth/approle/LICENSE @@ -1,14 +1,45 @@ License text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved. -“Business Source License” is a trademark of MariaDB Corporation Ab. +"Business Source License" is a trademark of MariaDB Corporation Ab. Parameters Licensor: HashiCorp, Inc. -Licensed Work: Vault 1.15.0. The Licensed Work is (c) 2023 HashiCorp, Inc. -Additional Use Grant: You may make production use of the Licensed Work, - provided such use does not include offering the Licensed Work - to third parties on a hosted or embedded basis which is - competitive with HashiCorp's products. +Licensed Work: Vault Version 1.15.0 or later. The Licensed Work is (c) 2024 + HashiCorp, Inc. +Additional Use Grant: You may make production use of the Licensed Work, provided + Your use does not include offering the Licensed Work to third + parties on a hosted or embedded basis in order to compete with + HashiCorp's paid version(s) of the Licensed Work. For purposes + of this license: + + A "competitive offering" is a Product that is offered to third + parties on a paid basis, including through paid support + arrangements, that significantly overlaps with the capabilities + of HashiCorp's paid version(s) of the Licensed Work. If Your + Product is not a competitive offering when You first make it + generally available, it will not become a competitive offering + later due to HashiCorp releasing a new version of the Licensed + Work with additional capabilities. In addition, Products that + are not provided on a paid basis are not competitive. + + "Product" means software that is offered to end users to manage + in their own environments or offered as a service on a hosted + basis. + + "Embedded" means including the source code or executable code + from the Licensed Work in a competitive offering. "Embedded" + also means packaging the competitive offering in such a way + that the Licensed Work must be accessed or downloaded for the + competitive offering to operate. + + Hosting or using the Licensed Work(s) for internal purposes + within an organization is not considered a competitive + offering. HashiCorp considers your organization to include all + of your affiliates under common control. + + For binding interpretive guidance on using HashiCorp products + under the Business Source License, please visit our FAQ. + (https://www.hashicorp.com/license-faq) Change Date: Four years from the date the Licensed Work is published. Change License: MPL 2.0 @@ -55,7 +86,7 @@ Licensor or its affiliates (provided that you may use a trademark or logo of Licensor as expressly required by this License). TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON -AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, +AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE. diff --git a/vendor/github.com/hashicorp/vault/api/auth/kubernetes/LICENSE b/vendor/github.com/hashicorp/vault/api/auth/kubernetes/LICENSE index 0ac557c3e18..503326e6260 100644 --- a/vendor/github.com/hashicorp/vault/api/auth/kubernetes/LICENSE +++ b/vendor/github.com/hashicorp/vault/api/auth/kubernetes/LICENSE @@ -1,14 +1,45 @@ License text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved. -“Business Source License” is a trademark of MariaDB Corporation Ab. +"Business Source License" is a trademark of MariaDB Corporation Ab. Parameters Licensor: HashiCorp, Inc. -Licensed Work: Vault 1.15.0. The Licensed Work is (c) 2023 HashiCorp, Inc. -Additional Use Grant: You may make production use of the Licensed Work, - provided such use does not include offering the Licensed Work - to third parties on a hosted or embedded basis which is - competitive with HashiCorp's products. +Licensed Work: Vault Version 1.15.0 or later. The Licensed Work is (c) 2024 + HashiCorp, Inc. +Additional Use Grant: You may make production use of the Licensed Work, provided + Your use does not include offering the Licensed Work to third + parties on a hosted or embedded basis in order to compete with + HashiCorp's paid version(s) of the Licensed Work. For purposes + of this license: + + A "competitive offering" is a Product that is offered to third + parties on a paid basis, including through paid support + arrangements, that significantly overlaps with the capabilities + of HashiCorp's paid version(s) of the Licensed Work. If Your + Product is not a competitive offering when You first make it + generally available, it will not become a competitive offering + later due to HashiCorp releasing a new version of the Licensed + Work with additional capabilities. In addition, Products that + are not provided on a paid basis are not competitive. + + "Product" means software that is offered to end users to manage + in their own environments or offered as a service on a hosted + basis. + + "Embedded" means including the source code or executable code + from the Licensed Work in a competitive offering. "Embedded" + also means packaging the competitive offering in such a way + that the Licensed Work must be accessed or downloaded for the + competitive offering to operate. + + Hosting or using the Licensed Work(s) for internal purposes + within an organization is not considered a competitive + offering. HashiCorp considers your organization to include all + of your affiliates under common control. + + For binding interpretive guidance on using HashiCorp products + under the Business Source License, please visit our FAQ. + (https://www.hashicorp.com/license-faq) Change Date: Four years from the date the Licensed Work is published. Change License: MPL 2.0 @@ -55,7 +86,7 @@ Licensor or its affiliates (provided that you may use a trademark or logo of Licensor as expressly required by this License). TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON -AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, +AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE. diff --git a/vendor/github.com/imdario/mergo/CONTRIBUTING.md b/vendor/github.com/imdario/mergo/CONTRIBUTING.md new file mode 100644 index 00000000000..0a1ff9f94d8 --- /dev/null +++ b/vendor/github.com/imdario/mergo/CONTRIBUTING.md @@ -0,0 +1,112 @@ + +# Contributing to mergo + +First off, thanks for taking the time to contribute! ❤️ + +All types of contributions are encouraged and valued. See the [Table of Contents](#table-of-contents) for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉 + +> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about: +> - Star the project +> - Tweet about it +> - Refer this project in your project's readme +> - Mention the project at local meetups and tell your friends/colleagues + + +## Table of Contents + +- [Code of Conduct](#code-of-conduct) +- [I Have a Question](#i-have-a-question) +- [I Want To Contribute](#i-want-to-contribute) +- [Reporting Bugs](#reporting-bugs) +- [Suggesting Enhancements](#suggesting-enhancements) + +## Code of Conduct + +This project and everyone participating in it is governed by the +[mergo Code of Conduct](https://github.com/imdario/mergoblob/master/CODE_OF_CONDUCT.md). +By participating, you are expected to uphold this code. Please report unacceptable behavior +to <>. + + +## I Have a Question + +> If you want to ask a question, we assume that you have read the available [Documentation](https://pkg.go.dev/github.com/imdario/mergo). + +Before you ask a question, it is best to search for existing [Issues](https://github.com/imdario/mergo/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first. + +If you then still feel the need to ask a question and need clarification, we recommend the following: + +- Open an [Issue](https://github.com/imdario/mergo/issues/new). +- Provide as much context as you can about what you're running into. +- Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant. + +We will then take care of the issue as soon as possible. + +## I Want To Contribute + +> ### Legal Notice +> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license. + +### Reporting Bugs + + +#### Before Submitting a Bug Report + +A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible. + +- Make sure that you are using the latest version. +- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](). If you are looking for support, you might want to check [this section](#i-have-a-question)). +- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/imdario/mergoissues?q=label%3Abug). +- Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue. +- Collect information about the bug: +- Stack trace (Traceback) +- OS, Platform and Version (Windows, Linux, macOS, x86, ARM) +- Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant. +- Possibly your input and the output +- Can you reliably reproduce the issue? And can you also reproduce it with older versions? + + +#### How Do I Submit a Good Bug Report? + +> You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to . + + +We use GitHub issues to track bugs and errors. If you run into an issue with the project: + +- Open an [Issue](https://github.com/imdario/mergo/issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.) +- Explain the behavior you would expect and the actual behavior. +- Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case. +- Provide the information you collected in the previous section. + +Once it's filed: + +- The project team will label the issue accordingly. +- A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps and mark the issue as `needs-repro`. Bugs with the `needs-repro` tag will not be addressed until they are reproduced. +- If the team is able to reproduce the issue, it will be marked `needs-fix`, as well as possibly other tags (such as `critical`), and the issue will be left to be implemented by someone. + +### Suggesting Enhancements + +This section guides you through submitting an enhancement suggestion for mergo, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions. + + +#### Before Submitting an Enhancement + +- Make sure that you are using the latest version. +- Read the [documentation]() carefully and find out if the functionality is already covered, maybe by an individual configuration. +- Perform a [search](https://github.com/imdario/mergo/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. +- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library. + + +#### How Do I Submit a Good Enhancement Suggestion? + +Enhancement suggestions are tracked as [GitHub issues](https://github.com/imdario/mergo/issues). + +- Use a **clear and descriptive title** for the issue to identify the suggestion. +- Provide a **step-by-step description of the suggested enhancement** in as many details as possible. +- **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you. +- You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. +- **Explain why this enhancement would be useful** to most mergo users. You may also want to point out the other projects that solved it better and which could serve as inspiration. + + +## Attribution +This guide is based on the **contributing-gen**. [Make your own](https://github.com/bttger/contributing-gen)! diff --git a/vendor/github.com/imdario/mergo/README.md b/vendor/github.com/imdario/mergo/README.md index 7e6f7aeee82..ffbbb62c704 100644 --- a/vendor/github.com/imdario/mergo/README.md +++ b/vendor/github.com/imdario/mergo/README.md @@ -1,17 +1,20 @@ # Mergo - -[![GoDoc][3]][4] [![GitHub release][5]][6] [![GoCard][7]][8] -[![Build Status][1]][2] -[![Coverage Status][9]][10] +[![Test status][1]][2] +[![OpenSSF Scorecard][21]][22] +[![OpenSSF Best Practices][19]][20] +[![Coverage status][9]][10] [![Sourcegraph][11]][12] -[![FOSSA Status][13]][14] +[![FOSSA status][13]][14] + +[![GoDoc][3]][4] [![Become my sponsor][15]][16] +[![Tidelift][17]][18] -[1]: https://travis-ci.org/imdario/mergo.png -[2]: https://travis-ci.org/imdario/mergo +[1]: https://github.com/imdario/mergo/workflows/tests/badge.svg?branch=master +[2]: https://github.com/imdario/mergo/actions/workflows/tests.yml [3]: https://godoc.org/github.com/imdario/mergo?status.svg [4]: https://godoc.org/github.com/imdario/mergo [5]: https://img.shields.io/github/release/imdario/mergo.svg @@ -26,6 +29,12 @@ [14]: https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_shield [15]: https://img.shields.io/github/sponsors/imdario [16]: https://github.com/sponsors/imdario +[17]: https://tidelift.com/badges/package/go/github.com%2Fimdario%2Fmergo +[18]: https://tidelift.com/subscription/pkg/go-github.com-imdario-mergo +[19]: https://bestpractices.coreinfrastructure.org/projects/7177/badge +[20]: https://bestpractices.coreinfrastructure.org/projects/7177 +[21]: https://api.securityscorecards.dev/projects/github.com/imdario/mergo/badge +[22]: https://api.securityscorecards.dev/projects/github.com/imdario/mergo A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements. @@ -55,7 +64,6 @@ If Mergo is useful to you, consider buying me a coffee, a beer, or making a mont ### Mergo in the wild -- [cli/cli](https://github.com/cli/cli) - [moby/moby](https://github.com/moby/moby) - [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) - [vmware/dispatch](https://github.com/vmware/dispatch) @@ -231,5 +239,4 @@ Written by [Dario Castañé](http://dario.im). [BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) license, as [Go language](http://golang.org/LICENSE). - [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fimdario%2Fmergo.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_large) diff --git a/vendor/github.com/imdario/mergo/SECURITY.md b/vendor/github.com/imdario/mergo/SECURITY.md new file mode 100644 index 00000000000..a5de61f77ba --- /dev/null +++ b/vendor/github.com/imdario/mergo/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| 0.3.x | :white_check_mark: | +| < 0.3 | :x: | + +## Security contact information + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. diff --git a/vendor/github.com/imdario/mergo/map.go b/vendor/github.com/imdario/mergo/map.go index a13a7ee46c7..b50d5c2a4e7 100644 --- a/vendor/github.com/imdario/mergo/map.go +++ b/vendor/github.com/imdario/mergo/map.go @@ -44,7 +44,7 @@ func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, conf } } // Remember, remember... - visited[h] = &visit{addr, typ, seen} + visited[h] = &visit{typ, seen, addr} } zeroValue := reflect.Value{} switch dst.Kind() { @@ -58,7 +58,7 @@ func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, conf } fieldName := field.Name fieldName = changeInitialCase(fieldName, unicode.ToLower) - if v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v)) || overwrite) { + if v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v), !config.ShouldNotDereference) || overwrite) { dstMap[fieldName] = src.Field(i).Interface() } } @@ -142,7 +142,7 @@ func MapWithOverwrite(dst, src interface{}, opts ...func(*Config)) error { func _map(dst, src interface{}, opts ...func(*Config)) error { if dst != nil && reflect.ValueOf(dst).Kind() != reflect.Ptr { - return ErrNonPointerAgument + return ErrNonPointerArgument } var ( vDst, vSrc reflect.Value diff --git a/vendor/github.com/imdario/mergo/merge.go b/vendor/github.com/imdario/mergo/merge.go index 8b4e2f47a08..0ef9b2138c1 100644 --- a/vendor/github.com/imdario/mergo/merge.go +++ b/vendor/github.com/imdario/mergo/merge.go @@ -38,10 +38,11 @@ func isExportedComponent(field *reflect.StructField) bool { } type Config struct { + Transformers Transformers Overwrite bool + ShouldNotDereference bool AppendSlice bool TypeCheck bool - Transformers Transformers overwriteWithEmptyValue bool overwriteSliceWithEmptyValue bool sliceDeepCopy bool @@ -76,7 +77,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co } } // Remember, remember... - visited[h] = &visit{addr, typ, seen} + visited[h] = &visit{typ, seen, addr} } if config.Transformers != nil && !isReflectNil(dst) && dst.IsValid() { @@ -95,7 +96,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co } } } else { - if dst.CanSet() && (isReflectNil(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc) { + if dst.CanSet() && (isReflectNil(dst) || overwrite) && (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc) { dst.Set(src) } } @@ -110,7 +111,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co } if src.Kind() != reflect.Map { - if overwrite { + if overwrite && dst.CanSet() { dst.Set(src) } return @@ -162,7 +163,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co dstSlice = reflect.ValueOf(dstElement.Interface()) } - if (!isEmptyValue(src) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice && !sliceDeepCopy { + if (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) && !config.AppendSlice && !sliceDeepCopy { if typeCheck && srcSlice.Type() != dstSlice.Type() { return fmt.Errorf("cannot override two slices with different type (%s, %s)", srcSlice.Type(), dstSlice.Type()) } @@ -194,22 +195,38 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co dst.SetMapIndex(key, dstSlice) } } - if dstElement.IsValid() && !isEmptyValue(dstElement) && (reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Map || reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Slice) { - continue + + if dstElement.IsValid() && !isEmptyValue(dstElement, !config.ShouldNotDereference) { + if reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Slice { + continue + } + if reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Map && reflect.TypeOf(dstElement.Interface()).Kind() == reflect.Map { + continue + } } - if srcElement.IsValid() && ((srcElement.Kind() != reflect.Ptr && overwrite) || !dstElement.IsValid() || isEmptyValue(dstElement)) { + if srcElement.IsValid() && ((srcElement.Kind() != reflect.Ptr && overwrite) || !dstElement.IsValid() || isEmptyValue(dstElement, !config.ShouldNotDereference)) { if dst.IsNil() { dst.Set(reflect.MakeMap(dst.Type())) } dst.SetMapIndex(key, srcElement) } } + + // Ensure that all keys in dst are deleted if they are not in src. + if overwriteWithEmptySrc { + for _, key := range dst.MapKeys() { + srcElement := src.MapIndex(key) + if !srcElement.IsValid() { + dst.SetMapIndex(key, reflect.Value{}) + } + } + } case reflect.Slice: if !dst.CanSet() { break } - if (!isEmptyValue(src) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice && !sliceDeepCopy { + if (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) && !config.AppendSlice && !sliceDeepCopy { dst.Set(src) } else if config.AppendSlice { if src.Type() != dst.Type() { @@ -244,12 +261,18 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co if src.Kind() != reflect.Interface { if dst.IsNil() || (src.Kind() != reflect.Ptr && overwrite) { - if dst.CanSet() && (overwrite || isEmptyValue(dst)) { + if dst.CanSet() && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) { dst.Set(src) } } else if src.Kind() == reflect.Ptr { - if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil { - return + if !config.ShouldNotDereference { + if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil { + return + } + } else { + if overwriteWithEmptySrc || (overwrite && !src.IsNil()) || dst.IsNil() { + dst.Set(src) + } } } else if dst.Elem().Type() == src.Type() { if err = deepMerge(dst.Elem(), src, visited, depth+1, config); err != nil { @@ -262,7 +285,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co } if dst.IsNil() || overwrite { - if dst.CanSet() && (overwrite || isEmptyValue(dst)) { + if dst.CanSet() && (overwrite || isEmptyValue(dst, !config.ShouldNotDereference)) { dst.Set(src) } break @@ -275,7 +298,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co break } default: - mustSet := (isEmptyValue(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc) + mustSet := (isEmptyValue(dst, !config.ShouldNotDereference) || overwrite) && (!isEmptyValue(src, !config.ShouldNotDereference) || overwriteWithEmptySrc) if mustSet { if dst.CanSet() { dst.Set(src) @@ -326,6 +349,12 @@ func WithOverrideEmptySlice(config *Config) { config.overwriteSliceWithEmptyValue = true } +// WithoutDereference prevents dereferencing pointers when evaluating whether they are empty +// (i.e. a non-nil pointer is never considered empty). +func WithoutDereference(config *Config) { + config.ShouldNotDereference = true +} + // WithAppendSlice will make merge append slices instead of overwriting it. func WithAppendSlice(config *Config) { config.AppendSlice = true @@ -344,7 +373,7 @@ func WithSliceDeepCopy(config *Config) { func merge(dst, src interface{}, opts ...func(*Config)) error { if dst != nil && reflect.ValueOf(dst).Kind() != reflect.Ptr { - return ErrNonPointerAgument + return ErrNonPointerArgument } var ( vDst, vSrc reflect.Value diff --git a/vendor/github.com/imdario/mergo/mergo.go b/vendor/github.com/imdario/mergo/mergo.go index 9fe362d476a..0a721e2d858 100644 --- a/vendor/github.com/imdario/mergo/mergo.go +++ b/vendor/github.com/imdario/mergo/mergo.go @@ -20,7 +20,7 @@ var ( ErrNotSupported = errors.New("only structs, maps, and slices are supported") ErrExpectedMapAsDestination = errors.New("dst was expected to be a map") ErrExpectedStructAsDestination = errors.New("dst was expected to be a struct") - ErrNonPointerAgument = errors.New("dst must be a pointer") + ErrNonPointerArgument = errors.New("dst must be a pointer") ) // During deepMerge, must keep track of checks that are @@ -28,13 +28,13 @@ var ( // checks in progress are true when it reencounters them. // Visited are stored in a map indexed by 17 * a1 + a2; type visit struct { - ptr uintptr typ reflect.Type next *visit + ptr uintptr } // From src/pkg/encoding/json/encode.go. -func isEmptyValue(v reflect.Value) bool { +func isEmptyValue(v reflect.Value, shouldDereference bool) bool { switch v.Kind() { case reflect.Array, reflect.Map, reflect.Slice, reflect.String: return v.Len() == 0 @@ -50,7 +50,10 @@ func isEmptyValue(v reflect.Value) bool { if v.IsNil() { return true } - return isEmptyValue(v.Elem()) + if shouldDereference { + return isEmptyValue(v.Elem(), shouldDereference) + } + return false case reflect.Func: return v.IsNil() case reflect.Invalid: diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/LICENSE b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/LICENSE new file mode 100644 index 00000000000..8dada3edaf5 --- /dev/null +++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/NOTICE b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/NOTICE new file mode 100644 index 00000000000..3e2901b3a69 --- /dev/null +++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/NOTICE @@ -0,0 +1 @@ +Copyright 2018 Kubernetes Network Plumbing Working Group diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/register.go b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/register.go new file mode 100644 index 00000000000..8ea2a30281b --- /dev/null +++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/register.go @@ -0,0 +1,5 @@ +package k8scnicncfio + +const ( + GroupName = "k8s.cni.cncf.io" +) diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/doc.go b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/doc.go new file mode 100644 index 00000000000..2882952a048 --- /dev/null +++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/doc.go @@ -0,0 +1,5 @@ +// +k8s:deepcopy-gen=package,register +// +groupName=k8s.cni.cncf.io +// +groupGoName=K8sCniCncfIo + +package v1 diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/register.go b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/register.go new file mode 100644 index 00000000000..e40da25728e --- /dev/null +++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/register.go @@ -0,0 +1,41 @@ +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + k8scnicncfio "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: k8scnicncfio.GroupName, Version: "v1"} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. + SchemeBuilder runtime.SchemeBuilder + localSchemeBuilder = &SchemeBuilder + AddToScheme = localSchemeBuilder.AddToScheme +) + +func init() { + // We only register manually written functions here. The registration of the + // generated functions takes place in the generated files. The separation + // makes the code compile even when the generated files are missing. + localSchemeBuilder.Register(addKnownTypes) +} + +// Adds the list of known types to api.Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &NetworkAttachmentDefinition{}, + &NetworkAttachmentDefinitionList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go new file mode 100644 index 00000000000..f96016baf6c --- /dev/null +++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go @@ -0,0 +1,202 @@ +package v1 + +import ( + "encoding/json" + "errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "net" +) + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +resourceName=network-attachment-definitions + +type NetworkAttachmentDefinition struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec NetworkAttachmentDefinitionSpec `json:"spec"` +} + +type NetworkAttachmentDefinitionSpec struct { + Config string `json:"config"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type NetworkAttachmentDefinitionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []NetworkAttachmentDefinition `json:"items"` +} + +// DNS contains values interesting for DNS resolvers +// +k8s:deepcopy-gen=false +type DNS struct { + Nameservers []string `json:"nameservers,omitempty"` + Domain string `json:"domain,omitempty"` + Search []string `json:"search,omitempty"` + Options []string `json:"options,omitempty"` +} + +const ( + DeviceInfoTypePCI = "pci" + DeviceInfoTypeVHostUser = "vhost-user" + DeviceInfoTypeMemif = "memif" + DeviceInfoTypeVDPA = "vdpa" + DeviceInfoVersion = "1.1.0" +) + +// DeviceInfo contains the information of the device associated +// with this network (if any) +type DeviceInfo struct { + Type string `json:"type,omitempty"` + Version string `json:"version,omitempty"` + Pci *PciDevice `json:"pci,omitempty"` + Vdpa *VdpaDevice `json:"vdpa,omitempty"` + VhostUser *VhostDevice `json:"vhost-user,omitempty"` + Memif *MemifDevice `json:"memif,omitempty"` +} + +type PciDevice struct { + PciAddress string `json:"pci-address,omitempty"` + Vhostnet string `json:"vhost-net,omitempty"` + RdmaDevice string `json:"rdma-device,omitempty"` + PfPciAddress string `json:"pf-pci-address,omitempty"` + RepresentorDevice string `json:"representor-device,omitempty"` +} + +type VdpaDevice struct { + ParentDevice string `json:"parent-device,omitempty"` + Driver string `json:"driver,omitempty"` + Path string `json:"path,omitempty"` + PciAddress string `json:"pci-address,omitempty"` + PfPciAddress string `json:"pf-pci-address,omitempty"` + RepresentorDevice string `json:"representor-device,omitempty"` +} + +const ( + VhostDeviceModeClient = "client" + VhostDeviceModeServer = "server" +) + +type VhostDevice struct { + Mode string `json:"mode,omitempty"` + Path string `json:"path,omitempty"` +} + +const ( + MemifDeviceRoleMaster = "master" + MemitDeviceRoleSlave = "slave" + MemifDeviceModeEthernet = "ethernet" + MemitDeviceModeIP = "ip" + MemitDeviceModePunt = "punt" +) + +type MemifDevice struct { + Role string `json:"role,omitempty"` + Path string `json:"path,omitempty"` + Mode string `json:"mode,omitempty"` +} + +// NetworkStatus is for network status annotation for pod +// +k8s:deepcopy-gen=false +type NetworkStatus struct { + Name string `json:"name"` + Interface string `json:"interface,omitempty"` + IPs []string `json:"ips,omitempty"` + Mac string `json:"mac,omitempty"` + Mtu int `json:"mtu,omitempty"` + Default bool `json:"default,omitempty"` + DNS DNS `json:"dns,omitempty"` + DeviceInfo *DeviceInfo `json:"device-info,omitempty"` + Gateway []string `json:"gateway,omitempty"` +} + +// PortMapEntry for CNI PortMapEntry +// +k8s:deepcopy-gen=false +type PortMapEntry struct { + HostPort int `json:"hostPort"` + ContainerPort int `json:"containerPort"` + Protocol string `json:"protocol,omitempty"` + HostIP string `json:"hostIP,omitempty"` +} + +// BandwidthEntry for CNI BandwidthEntry +// +k8s:deepcopy-gen=false +type BandwidthEntry struct { + IngressRate int `json:"ingressRate"` + IngressBurst int `json:"ingressBurst"` + + EgressRate int `json:"egressRate"` + EgressBurst int `json:"egressBurst"` +} + +// NetworkSelectionElement represents one element of the JSON format +// Network Attachment Selection Annotation as described in section 4.1.2 +// of the CRD specification. +// +k8s:deepcopy-gen=false +type NetworkSelectionElement struct { + // Name contains the name of the Network object this element selects + Name string `json:"name"` + // Namespace contains the optional namespace that the network referenced + // by Name exists in + Namespace string `json:"namespace,omitempty"` + // IPRequest contains an optional requested IP addresses for this network + // attachment + IPRequest []string `json:"ips,omitempty"` + // MacRequest contains an optional requested MAC address for this + // network attachment + MacRequest string `json:"mac,omitempty"` + // InfinibandGUIDRequest contains an optional requested Infiniband GUID + // address for this network attachment + InfinibandGUIDRequest string `json:"infiniband-guid,omitempty"` + // InterfaceRequest contains an optional requested name for the + // network interface this attachment will create in the container + InterfaceRequest string `json:"interface,omitempty"` + // PortMappingsRequest contains an optional requested port mapping + // for the network + PortMappingsRequest []*PortMapEntry `json:"portMappings,omitempty"` + // BandwidthRequest contains an optional requested bandwidth for + // the network + BandwidthRequest *BandwidthEntry `json:"bandwidth,omitempty"` + // CNIArgs contains additional CNI arguments for the network interface + CNIArgs *map[string]interface{} `json:"cni-args,omitempty"` + // GatewayRequest contains default route IP address for the pod + GatewayRequest []net.IP `json:"default-route,omitempty"` + // IPAMClaimReference container the IPAMClaim name where the IPs for this + // attachment will be located. + IPAMClaimReference string `json:"ipam-claim-reference,omitempty"` +} + +func (nse *NetworkSelectionElement) UnmarshalJSON(b []byte) error { + type networkSelectionElement NetworkSelectionElement + + var netSelectionElement networkSelectionElement + if err := json.Unmarshal(b, &netSelectionElement); err != nil { + return err + } + if len(netSelectionElement.IPRequest) > 0 && netSelectionElement.IPAMClaimReference != "" { + return TooManyIPSources + } + *nse = NetworkSelectionElement(netSelectionElement) + return nil +} + +const ( + // Pod annotation for network-attachment-definition + NetworkAttachmentAnnot = "k8s.v1.cni.cncf.io/networks" + // Pod annotation for network status + NetworkStatusAnnot = "k8s.v1.cni.cncf.io/network-status" +) + +// NoK8sNetworkError indicates error, no network in kubernetes +// +k8s:deepcopy-gen=false +type NoK8sNetworkError struct { + Message string +} + +func (e *NoK8sNetworkError) Error() string { return string(e.Message) } + +var TooManyIPSources = errors.New("cannot provide a static IP and a reference of an IPAM claim in the same network selection element") diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/zz_generated.deepcopy.go b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..9a7b1fcce8c --- /dev/null +++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/zz_generated.deepcopy.go @@ -0,0 +1,202 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2021 The Kubernetes Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeviceInfo) DeepCopyInto(out *DeviceInfo) { + *out = *in + if in.Pci != nil { + in, out := &in.Pci, &out.Pci + *out = new(PciDevice) + **out = **in + } + if in.Vdpa != nil { + in, out := &in.Vdpa, &out.Vdpa + *out = new(VdpaDevice) + **out = **in + } + if in.VhostUser != nil { + in, out := &in.VhostUser, &out.VhostUser + *out = new(VhostDevice) + **out = **in + } + if in.Memif != nil { + in, out := &in.Memif, &out.Memif + *out = new(MemifDevice) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeviceInfo. +func (in *DeviceInfo) DeepCopy() *DeviceInfo { + if in == nil { + return nil + } + out := new(DeviceInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MemifDevice) DeepCopyInto(out *MemifDevice) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemifDevice. +func (in *MemifDevice) DeepCopy() *MemifDevice { + if in == nil { + return nil + } + out := new(MemifDevice) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkAttachmentDefinition) DeepCopyInto(out *NetworkAttachmentDefinition) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkAttachmentDefinition. +func (in *NetworkAttachmentDefinition) DeepCopy() *NetworkAttachmentDefinition { + if in == nil { + return nil + } + out := new(NetworkAttachmentDefinition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NetworkAttachmentDefinition) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkAttachmentDefinitionList) DeepCopyInto(out *NetworkAttachmentDefinitionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NetworkAttachmentDefinition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkAttachmentDefinitionList. +func (in *NetworkAttachmentDefinitionList) DeepCopy() *NetworkAttachmentDefinitionList { + if in == nil { + return nil + } + out := new(NetworkAttachmentDefinitionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NetworkAttachmentDefinitionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkAttachmentDefinitionSpec) DeepCopyInto(out *NetworkAttachmentDefinitionSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkAttachmentDefinitionSpec. +func (in *NetworkAttachmentDefinitionSpec) DeepCopy() *NetworkAttachmentDefinitionSpec { + if in == nil { + return nil + } + out := new(NetworkAttachmentDefinitionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PciDevice) DeepCopyInto(out *PciDevice) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PciDevice. +func (in *PciDevice) DeepCopy() *PciDevice { + if in == nil { + return nil + } + out := new(PciDevice) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VdpaDevice) DeepCopyInto(out *VdpaDevice) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VdpaDevice. +func (in *VdpaDevice) DeepCopy() *VdpaDevice { + if in == nil { + return nil + } + out := new(VdpaDevice) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VhostDevice) DeepCopyInto(out *VhostDevice) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VhostDevice. +func (in *VhostDevice) DeepCopy() *VhostDevice { + if in == nil { + return nil + } + out := new(VhostDevice) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/cniconfig.go b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/cniconfig.go new file mode 100644 index 00000000000..4b54909bbf1 --- /dev/null +++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/cniconfig.go @@ -0,0 +1,237 @@ +// Copyright (c) 2021 Kubernetes Network Plumbing Working Group +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package utils + +import ( + "encoding/json" + "fmt" + "github.com/containernetworking/cni/libcni" + "io/ioutil" + "os" + "path/filepath" + "strings" + + v1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" +) + +const ( + baseDevInfoPath = "/var/run/k8s.cni.cncf.io/devinfo" + dpDevInfoSubDir = "dp" + cniDevInfoSubDir = "cni" +) + +// GetCNIConfig (from annotation string to CNI JSON bytes) +func GetCNIConfig(net *v1.NetworkAttachmentDefinition, confDir string) (config []byte, err error) { + emptySpec := v1.NetworkAttachmentDefinitionSpec{} + if net.Spec == emptySpec { + // Network Spec empty; generate delegate from CNI JSON config + // from the configuration directory that has the same network + // name as the custom resource + config, err = GetCNIConfigFromFile(net.Name, confDir) + if err != nil { + return nil, fmt.Errorf("GetCNIConfig: err in GetCNIConfigFromFile: %v", err) + } + } else { + // Config contains a standard JSON-encoded CNI configuration + // or configuration list which defines the plugin chain to + // execute. + config, err = GetCNIConfigFromSpec(net.Spec.Config, net.Name) + if err != nil { + return nil, fmt.Errorf("GetCNIConfig: err in getCNIConfigFromSpec: %v", err) + } + } + return config, nil +} + +// GetCNIConfigFromSpec reads a CNI JSON configuration from given directory (confDir) +func GetCNIConfigFromFile(name, confDir string) ([]byte, error) { + // In the absence of valid keys in a Spec, the runtime (or + // meta-plugin) should load and execute a CNI .configlist + // or .config (in that order) file on-disk whose JSON + // "name" key matches this Network object’s name. + + // In part, adapted from K8s pkg/kubelet/dockershim/network/cni/cni.go#getDefaultCNINetwork + files, err := libcni.ConfFiles(confDir, []string{".conf", ".json", ".conflist"}) + switch { + case err != nil: + return nil, fmt.Errorf("No networks found in %s", confDir) + case len(files) == 0: + return nil, fmt.Errorf("No networks found in %s", confDir) + } + + for _, confFile := range files { + var confList *libcni.NetworkConfigList + if strings.HasSuffix(confFile, ".conflist") { + confList, err = libcni.ConfListFromFile(confFile) + if err != nil { + return nil, fmt.Errorf("Error loading CNI conflist file %s: %v", confFile, err) + } + + if confList.Name == name || name == "" { + return confList.Bytes, nil + } + + } else { + conf, err := libcni.ConfFromFile(confFile) + if err != nil { + return nil, fmt.Errorf("Error loading CNI config file %s: %v", confFile, err) + } + + if conf.Network.Name == name || name == "" { + // Ensure the config has a "type" so we know what plugin to run. + // Also catches the case where somebody put a conflist into a conf file. + if conf.Network.Type == "" { + return nil, fmt.Errorf("Error loading CNI config file %s: no 'type'; perhaps this is a .conflist?", confFile) + } + return conf.Bytes, nil + } + } + } + + return nil, fmt.Errorf("no network available in the name %s in cni dir %s", name, confDir) +} + +// GetCNIConfigFromSpec reads a CNI JSON configuration from the NetworkAttachmentDefinition +// object's Spec.Config field and fills in any missing details like the network name +func GetCNIConfigFromSpec(configData, netName string) ([]byte, error) { + var rawConfig map[string]interface{} + var err error + + configBytes := []byte(configData) + err = json.Unmarshal(configBytes, &rawConfig) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal Spec.Config: %v", err) + } + + // Inject network name if missing from Config for the thick plugin case + if n, ok := rawConfig["name"]; !ok || n == "" { + rawConfig["name"] = netName + configBytes, err = json.Marshal(rawConfig) + if err != nil { + return nil, fmt.Errorf("failed to re-marshal Spec.Config: %v", err) + } + } + + return configBytes, nil +} + +// loadDeviceInfo loads a Device Information file +func loadDeviceInfo(path string) (*v1.DeviceInfo, error) { + var devInfo v1.DeviceInfo + + bytes, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + + err = json.Unmarshal(bytes, &devInfo) + if err != nil { + return nil, err + } + + return &devInfo, nil +} + +// cleanDeviceInfo removes a Device Information file +func cleanDeviceInfo(path string) error { + if _, err := os.Stat(path); !os.IsNotExist(err) { + return os.Remove(path) + } + return nil +} + +// saveDeviceInfo writes a Device Information file +func saveDeviceInfo(devInfo *v1.DeviceInfo, path string) error { + if devInfo == nil { + return fmt.Errorf("Device Information is null") + } + + dir := filepath.Dir(path) + if _, err := os.Stat(dir); os.IsNotExist(err) { + if err := os.MkdirAll(dir, os.ModeDir); err != nil { + return err + } + } + + if _, err := os.Stat(path); !os.IsNotExist(err) { + return fmt.Errorf("Device Information file already exists: %s", path) + } + + devInfoJSON, err := json.Marshal(devInfo) + if err != nil { + return err + } + + if err := ioutil.WriteFile(path, devInfoJSON, 0444); err != nil { + return err + } + return nil +} + +// getDPDeviceInfoPath returns the standard Device Plugin DevInfo filename +// This filename is fixed because Device Plugin and NPWG Implementation need +// to both access file and name is not passed between them. So name is generated +// from Resource Name and DeviceID. +func getDPDeviceInfoPath(resourceName string, deviceID string) string { + return filepath.Join(baseDevInfoPath, dpDevInfoSubDir, fmt.Sprintf("%s-%s-device.json", + strings.ReplaceAll(resourceName, "/", "-"), strings.ReplaceAll(deviceID, "/", "-"))) +} + +// GetCNIDeviceInfoPath returns the standard Device Plugin DevInfo filename +// The path is fixed but the filename is flexible and determined by the caller. +func GetCNIDeviceInfoPath(filename string) string { + return filepath.Join(baseDevInfoPath, cniDevInfoSubDir, strings.ReplaceAll(filename, "/", "-")) +} + +// LoadDeviceInfoFromDP loads a DeviceInfo structure from file created by a Device Plugin +// Returns an error if the device information is malformed and (nil, nil) if it does not exist +func LoadDeviceInfoFromDP(resourceName string, deviceID string) (*v1.DeviceInfo, error) { + return loadDeviceInfo(getDPDeviceInfoPath(resourceName, deviceID)) +} + +// SaveDeviceInfoForDP saves a DeviceInfo structure created by a Device Plugin +func SaveDeviceInfoForDP(resourceName string, deviceID string, devInfo *v1.DeviceInfo) error { + return saveDeviceInfo(devInfo, getDPDeviceInfoPath(resourceName, deviceID)) +} + +// CleanDeviceInfoForDP removes a DeviceInfo DP File. +func CleanDeviceInfoForDP(resourceName string, deviceID string) error { + return cleanDeviceInfo(getDPDeviceInfoPath(resourceName, deviceID)) +} + +// LoadDeviceInfoFromCNI loads a DeviceInfo structure from created by a CNI. +// Returns an error if the device information is malformed and (nil, nil) if it does not exist +func LoadDeviceInfoFromCNI(cniPath string) (*v1.DeviceInfo, error) { + return loadDeviceInfo(cniPath) +} + +// SaveDeviceInfoForCNI saves a DeviceInfo structure created by a CNI +func SaveDeviceInfoForCNI(cniPath string, devInfo *v1.DeviceInfo) error { + return saveDeviceInfo(devInfo, cniPath) +} + +// CopyDeviceInfoForCNIFromDP saves a DeviceInfo structure created by a DP to a CNI File. +func CopyDeviceInfoForCNIFromDP(cniPath string, resourceName string, deviceID string) error { + devInfo, err := loadDeviceInfo(getDPDeviceInfoPath(resourceName, deviceID)) + if err != nil { + return err + } + return saveDeviceInfo(devInfo, cniPath) +} + +// CleanDeviceInfoForCNI removes a DeviceInfo CNI File. +func CleanDeviceInfoForCNI(cniPath string) error { + return cleanDeviceInfo(cniPath) +} diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go new file mode 100644 index 00000000000..e865f396b81 --- /dev/null +++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go @@ -0,0 +1,268 @@ +// Copyright (c) 2021 Kubernetes Network Plumbing Working Group +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package utils + +import ( + "context" + "encoding/json" + "fmt" + "net" + "regexp" + "strings" + + cnitypes "github.com/containernetworking/cni/pkg/types" + cni100 "github.com/containernetworking/cni/pkg/types/100" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + v1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" + + corev1 "k8s.io/api/core/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/util/retry" +) + +// convertDNS converts CNI's DNS type to client DNS +func convertDNS(dns cnitypes.DNS) *v1.DNS { + var v1dns v1.DNS + + v1dns.Nameservers = append([]string{}, dns.Nameservers...) + v1dns.Domain = dns.Domain + v1dns.Search = append([]string{}, dns.Search...) + v1dns.Options = append([]string{}, dns.Options...) + + return &v1dns +} + +// SetNetworkStatus updates the Pod status +func SetNetworkStatus(client kubernetes.Interface, pod *corev1.Pod, statuses []v1.NetworkStatus) error { + if client == nil { + return fmt.Errorf("no client set") + } + + if pod == nil { + return fmt.Errorf("no pod set") + } + + var networkStatus []string + if statuses != nil { + for _, status := range statuses { + data, err := json.MarshalIndent(status, "", " ") + if err != nil { + return fmt.Errorf("SetNetworkStatus: error with Marshal Indent: %v", err) + } + networkStatus = append(networkStatus, string(data)) + } + } + + err := setPodNetworkStatus(client, pod, fmt.Sprintf("[%s]", strings.Join(networkStatus, ","))) + if err != nil { + return fmt.Errorf("SetNetworkStatus: failed to update the pod %s in out of cluster comm: %v", pod.Name, err) + } + return nil +} + +func setPodNetworkStatus(client kubernetes.Interface, pod *corev1.Pod, networkstatus string) error { + if len(pod.Annotations) == 0 { + pod.Annotations = make(map[string]string) + } + + coreClient := client.CoreV1() + var err error + name := pod.Name + namespace := pod.Namespace + + resultErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + pod, err = coreClient.Pods(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + if err != nil { + return err + } + + if len(pod.Annotations) == 0 { + pod.Annotations = make(map[string]string) + } + pod.Annotations[v1.NetworkStatusAnnot] = networkstatus + _, err = coreClient.Pods(namespace).UpdateStatus(context.TODO(), pod, metav1.UpdateOptions{}) + return err + }) + if resultErr != nil { + return fmt.Errorf("status update failed for pod %s/%s: %v", pod.Namespace, pod.Name, resultErr) + } + return nil +} + +// GetNetworkStatus returns pod's network status +func GetNetworkStatus(pod *corev1.Pod) ([]v1.NetworkStatus, error) { + if pod == nil { + return nil, fmt.Errorf("cannot find pod") + } + if pod.Annotations == nil { + return nil, fmt.Errorf("cannot find pod annotation") + } + + netStatusesJson, ok := pod.Annotations[v1.NetworkStatusAnnot] + if !ok { + return nil, fmt.Errorf("cannot find network status") + } + + var netStatuses []v1.NetworkStatus + err := json.Unmarshal([]byte(netStatusesJson), &netStatuses) + + return netStatuses, err +} + +// CreateNetworkStatus create NetworkStatus from CNI result +func CreateNetworkStatus(r cnitypes.Result, networkName string, defaultNetwork bool, dev *v1.DeviceInfo) (*v1.NetworkStatus, error) { + netStatus := &v1.NetworkStatus{} + netStatus.Name = networkName + netStatus.Default = defaultNetwork + + // Convert whatever the IPAM result was into the current Result type + result, err := cni100.NewResultFromResult(r) + if err != nil { + return netStatus, fmt.Errorf("error convert the type.Result to cni100.Result: %v", err) + } + + for _, ifs := range result.Interfaces { + // Only pod interfaces can have sandbox information + if ifs.Sandbox != "" { + netStatus.Interface = ifs.Name + netStatus.Mac = ifs.Mac + netStatus.Mtu = ifs.Mtu + } + } + + for _, ipconfig := range result.IPs { + netStatus.IPs = append(netStatus.IPs, ipconfig.Address.IP.String()) + } + + for _, route := range result.Routes { + if isDefaultRoute(route) { + netStatus.Gateway = append(netStatus.Gateway, route.GW.String()) + } + } + + v1dns := convertDNS(result.DNS) + netStatus.DNS = *v1dns + + if dev != nil { + netStatus.DeviceInfo = dev + } + + return netStatus, nil +} + +func isDefaultRoute(route *cnitypes.Route) bool { + return route.Dst.IP == nil && route.Dst.Mask == nil || + route.Dst.IP.Equal(net.IPv4zero) || + route.Dst.IP.Equal(net.IPv6zero) +} + +// ParsePodNetworkAnnotation parses Pod annotation for net-attach-def and get NetworkSelectionElement +func ParsePodNetworkAnnotation(pod *corev1.Pod) ([]*v1.NetworkSelectionElement, error) { + netAnnot := pod.Annotations[v1.NetworkAttachmentAnnot] + defaultNamespace := pod.Namespace + + if len(netAnnot) == 0 { + return nil, &v1.NoK8sNetworkError{Message: "no kubernetes network found"} + } + + networks, err := ParseNetworkAnnotation(netAnnot, defaultNamespace) + if err != nil { + return nil, err + } + return networks, nil +} + +// ParseNetworkAnnotation parses actual annotation string and get NetworkSelectionElement +func ParseNetworkAnnotation(podNetworks, defaultNamespace string) ([]*v1.NetworkSelectionElement, error) { + var networks []*v1.NetworkSelectionElement + + if podNetworks == "" { + return nil, fmt.Errorf("parsePodNetworkAnnotation: pod annotation not having \"network\" as key") + } + + if strings.IndexAny(podNetworks, "[{\"") >= 0 { + if err := json.Unmarshal([]byte(podNetworks), &networks); err != nil { + return nil, fmt.Errorf("parsePodNetworkAnnotation: failed to parse pod Network Attachment Selection Annotation JSON format: %v", err) + } + } else { + // Comma-delimited list of network attachment object names + for _, item := range strings.Split(podNetworks, ",") { + // Remove leading and trailing whitespace. + item = strings.TrimSpace(item) + + // Parse network name (i.e. /@) + netNsName, networkName, netIfName, err := parsePodNetworkObjectText(item) + if err != nil { + return nil, fmt.Errorf("parsePodNetworkAnnotation: %v", err) + } + + networks = append(networks, &v1.NetworkSelectionElement{ + Name: networkName, + Namespace: netNsName, + InterfaceRequest: netIfName, + }) + } + } + + for _, net := range networks { + if net.Namespace == "" { + net.Namespace = defaultNamespace + } + } + + return networks, nil +} + +// parsePodNetworkObjectText parses annotation text and returns +// its triplet, (namespace, name, interface name). +func parsePodNetworkObjectText(podnetwork string) (string, string, string, error) { + var netNsName string + var netIfName string + var networkName string + + slashItems := strings.Split(podnetwork, "/") + if len(slashItems) == 2 { + netNsName = strings.TrimSpace(slashItems[0]) + networkName = slashItems[1] + } else if len(slashItems) == 1 { + networkName = slashItems[0] + } else { + return "", "", "", fmt.Errorf("Invalid network object (failed at '/')") + } + + atItems := strings.Split(networkName, "@") + networkName = strings.TrimSpace(atItems[0]) + if len(atItems) == 2 { + netIfName = strings.TrimSpace(atItems[1]) + } else if len(atItems) != 1 { + return "", "", "", fmt.Errorf("Invalid network object (failed at '@')") + } + + // Check and see if each item matches the specification for valid attachment name. + // "Valid attachment names must be comprised of units of the DNS-1123 label format" + // [a-z0-9]([-a-z0-9]*[a-z0-9])? + // And we allow at (@), and forward slash (/) (units separated by commas) + // It must start and end alphanumerically. + allItems := []string{netNsName, networkName, netIfName} + for i := range allItems { + matched, _ := regexp.MatchString("^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", allItems[i]) + if !matched && len([]rune(allItems[i])) > 0 { + return "", "", "", fmt.Errorf(fmt.Sprintf("Failed to parse: one or more items did not match comma-delimited format (must consist of lower case alphanumeric characters). Must start and end with an alphanumeric character), mismatch @ '%v'", allItems[i])) + } + } + + return netNsName, networkName, netIfName, nil +} diff --git a/vendor/github.com/kube-object-storage/lib-bucket-provisioner/LICENSE b/vendor/github.com/kube-object-storage/lib-bucket-provisioner/LICENSE new file mode 100644 index 00000000000..8e8487438ac --- /dev/null +++ b/vendor/github.com/kube-object-storage/lib-bucket-provisioner/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 The Rook Authors. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/register.go b/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/register.go new file mode 100644 index 00000000000..1eaa355615a --- /dev/null +++ b/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/register.go @@ -0,0 +1,19 @@ +/* +Copyright 2019 Red Hat Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package objectbucket_io + +const GroupName = "objectbucket.io" diff --git a/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/doc.go b/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/doc.go new file mode 100644 index 00000000000..d0d5e06f529 --- /dev/null +++ b/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2019 Red Hat Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1alpha1 contains API Schema definitions for the objectbucket v1alpha1 API group +// +k8s:deepcopy-gen=package,register +// +groupName=objectbucket.io +package v1alpha1 diff --git a/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/objectbucket_types.go b/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/objectbucket_types.go new file mode 100644 index 00000000000..71f761e8b86 --- /dev/null +++ b/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/objectbucket_types.go @@ -0,0 +1,161 @@ +/* +Copyright 2019 Red Hat Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ObjectBucketKind = "ObjectBucket" + +func ObjectBucketGVK() schema.GroupVersionKind { + return GroupKindVersion(ObjectBucketKind) +} + +type mapper interface { + toMap() map[string]string +} + +// Exported constants used by provisioners: including conventional +// environment variable names for S3 Access and Secret Key, and +// map key names. Eg. key to access a bucket name in a storage class +// used for brownfield buckets, or the key to create an OB's +// Authentication{}. +const ( + AwsKeyField = "AWS_ACCESS_KEY_ID" + AwsSecretField = "AWS_SECRET_ACCESS_KEY" + StorageClassBucket = "bucketName" +) + +// AccessKeys is an Authentication type for passing AWS S3 style key pairs from the provisioner to the reconciler +type AccessKeys struct { + // AccessKeyId is the S3 style access key to be written to a secret + AccessKeyID string `json:"-"` + // SecretAccessKey is the S3 style secret key to be written to a secret + SecretAccessKey string `json:"-"` +} + +var _ mapper = &AccessKeys{} + +func (ak *AccessKeys) toMap() map[string]string { + return map[string]string{ + AwsKeyField: ak.AccessKeyID, + AwsSecretField: ak.SecretAccessKey, + } +} + +// Authentication wraps all supported auth types. The design choice enables expansion of supported types while +// protecting backwards compatibility. +type Authentication struct { + AccessKeys *AccessKeys `json:"-"` + AdditionalSecretData map[string]string `json:"-"` +} + +// ToMap converts the any defined authentication type into a map[string]string for writing to a Secret.StringData field +func (a *Authentication) ToMap() map[string]string { + if a == nil { + return map[string]string{} + } + if a.AccessKeys != nil { + return a.AccessKeys.toMap() + } + return map[string]string{} +} + +// Endpoint contains all connection relevant data that an app may require for accessing +// the bucket +type Endpoint struct { + BucketHost string `json:"bucketHost"` + BucketPort int `json:"bucketPort"` + BucketName string `json:"bucketName"` + Region string `json:"region"` + SubRegion string `json:"subRegion"` + AdditionalConfigData map[string]string `json:"additionalConfig"` +} + +// Connection encapsulates Endpoint and Authentication data to simplify the expected return values of the Provision() +// interface method. This makes it more clear to library consumers what specific values they should return from their +// Provisioner interface implementation. +type Connection struct { + Endpoint *Endpoint `json:"endpoint"` + Authentication *Authentication `json:"-"` + AdditionalState map[string]string `json:"additionalState"` +} + +// ObjectBucketSpec defines the desired state of ObjectBucket. Fields defined here should be normal among all providers. +// Authentication must be of a type defined in this package to pass type checks in reconciler +type ObjectBucketSpec struct { + StorageClassName string `json:"storageClassName"` + ReclaimPolicy *corev1.PersistentVolumeReclaimPolicy `json:"reclaimPolicy"` + ClaimRef *corev1.ObjectReference `json:"claimRef"` + *Connection `json:",inline"` +} + +// ObjectBucketStatusPhase is set by the controller to save the state of the provisioning process. +type ObjectBucketStatusPhase string + +const ( + // ObjectBucketStatusPhaseBound indicates that the objectBucket has been logically bound to a claim following a + // successful provision. It is NOT the authority for the status of the claim an object bucket. For that, see + // objectBucketClaim.Spec.ObjectBucketName + ObjectBucketStatusPhaseBound ObjectBucketStatusPhase = "Bound" + // ObjectBucketStatusPhaseReleased indicates that the object bucket was once bound to a claim that has since been deleted + // this phase can occur when the claim is deleted and the reconciler is in the process of either deleting the bucket or + // revoking access to that bucket in the case of brownfield. + ObjectBucketStatusPhaseReleased ObjectBucketStatusPhase = "Released" + // ObjectBucketStatusPhaseFailed TODO this phase does not have a defined reason for existing. If provisioning fails + // the OB is cleaned up. Since we generate OBs for brownfield cases, we also would delete them on failures. The + // result is that if this phase is set, the OB would deleted soon after anyway. + ObjectBucketStatusPhaseFailed ObjectBucketStatusPhase = "Failed" +) + +// ObjectBucketStatus defines the observed state of ObjectBucket +type ObjectBucketStatus struct { + Phase ObjectBucketStatusPhase `json:"phase"` +} + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:openapi-gen=true +// +kubebuilder:resource:scope=Cluster,shortName=ob;obs +// +kubebuilder:printcolumn:name="StorageClass",type="string",JSONPath=".spec.storageClassName",description="StorageClass" +// +kubebuilder:printcolumn:name="ClaimNamespace",type="string",JSONPath=".spec.claimRef.namespace",description="ClaimNamespace" +// +kubebuilder:printcolumn:name="ClaimName",type="string",JSONPath=".spec.claimRef.name",description="ClaimName" +// +kubebuilder:printcolumn:name="ReclaimPolicy",type="string",JSONPath=".spec.reclaimPolicy",description="ReclaimPolicy" +// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase",description="Phase" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" + +// ObjectBucket is the Schema for the objectbuckets API +type ObjectBucket struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ObjectBucketSpec `json:"spec,omitempty"` + Status ObjectBucketStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ObjectBucketList contains a list of ObjectBucket +type ObjectBucketList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ObjectBucket `json:"items"` +} diff --git a/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/objectbucketclaim_types.go b/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/objectbucketclaim_types.go new file mode 100644 index 00000000000..9ffdf8400dd --- /dev/null +++ b/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/objectbucketclaim_types.go @@ -0,0 +1,105 @@ +/* +Copyright 2019 Red Hat Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ObjectBucketClaimKind = "ObjectBucketClaim" + +func ObjectBucketClaimGVK() schema.GroupVersionKind { + return GroupKindVersion(ObjectBucketClaimKind) +} + +// ObjectBucketClaimSpec defines the desired state of ObjectBucketClaim +type ObjectBucketClaimSpec struct { + + // StorageClass names the StorageClass object representing the desired provisioner and parameters + StorageClassName string `json:"storageClassName"` + + // BucketName (not recommended) the name of the bucket. Caution! + // In-store bucket names may collide across namespaces. If you define + // the name yourself, try to make it as unique as possible. + // +optional + BucketName string `json:"bucketName,omityempty"` + + // GenerateBucketName (recommended) a prefix for a bucket name to be + // followed by a hyphen and 5 random characters. Protects against + // in-store name collisions. + // +optional + GenerateBucketName string `json:"generateBucketName,omitempty"` + + // AdditionalConfig gives providers a location to set + // proprietary config values (tenant, namespace, etc) + // +optional + AdditionalConfig map[string]string `json:"additionalConfig,omitempty"` + + // ObjectBucketName is the name of the object bucket resource. This is the authoritative + // determination for binding. + ObjectBucketName string `json:"objectBucketName,omitempty"` +} + +// ObjectBucketClaimStatusPhase is set by the controller to save the state of the provisioning process. +type ObjectBucketClaimStatusPhase string + +const ( + // ObjectBucketClaimStatusPhasePending indicates that the provisioner has begun handling the request and that it is + // still in process + ObjectBucketClaimStatusPhasePending = "Pending" + // ObjectBucketClaimStatusPhaseBound indicates that provisioning has succeeded, the objectBucket is marked bound, and + // there is now a configMap and secret containing the appropriate bucket data in the namespace of the claim + ObjectBucketClaimStatusPhaseBound = "Bound" + // ObjectBucketClaimStatusPhaseReleased TODO this would likely mean that the OB was deleted. That situation should never + // happen outside of the claim being deleted. So this state shouldn't naturally arise out of automation. + ObjectBucketClaimStatusPhaseReleased = "Released" + // ObjectBucketClaimStatusPhaseFailed indicates that provisioning failed. There should be no configMap, secret, or + // object bucket and no bucket should be left hanging in the object store + ObjectBucketClaimStatusPhaseFailed = "Failed" +) + +// ObjectBucketClaimStatus defines the observed state of ObjectBucketClaim +type ObjectBucketClaimStatus struct { + Phase ObjectBucketClaimStatusPhase `json:"phase,omitempty"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:openapi-gen=true +// +kubebuilder:resource:shortName=obc;obcs +// +kubebuilder:printcolumn:name="StorageClass",type="string",JSONPath=".spec.storageClassName",description="StorageClass" +// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase",description="Phase" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" + +// ObjectBucketClaim is the Schema for the objectbucketclaims API +type ObjectBucketClaim struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ObjectBucketClaimSpec `json:"spec,omitempty"` + Status ObjectBucketClaimStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ObjectBucketClaimList contains a list of ObjectBucketClaim +type ObjectBucketClaimList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ObjectBucketClaim `json:"items"` +} diff --git a/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/register.go b/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/register.go new file mode 100644 index 00000000000..057eb647ec7 --- /dev/null +++ b/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/register.go @@ -0,0 +1,64 @@ +/* +Copyright 2019 Red Hat Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1alpha1 contains API Schema definitions for the objectbucket v1alpha1 API group +// +k8s:deepcopy-gen=package,register +// +groupName=objectbucket.io +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + objectbucketio "github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: objectbucketio.GroupName, Version: "v1alpha1"} + +const Version = "v1alpha1" + +func GroupKindVersion(kind string) schema.GroupVersionKind { + return SchemeGroupVersion.WithKind(kind) +} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &ObjectBucketClaim{}, + &ObjectBucketClaimList{}, + &ObjectBucket{}, + &ObjectBucketList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..3c69cd05472 --- /dev/null +++ b/vendor/github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,335 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2019 Red Hat Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AccessKeys) DeepCopyInto(out *AccessKeys) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessKeys. +func (in *AccessKeys) DeepCopy() *AccessKeys { + if in == nil { + return nil + } + out := new(AccessKeys) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Authentication) DeepCopyInto(out *Authentication) { + *out = *in + if in.AccessKeys != nil { + in, out := &in.AccessKeys, &out.AccessKeys + *out = new(AccessKeys) + **out = **in + } + if in.AdditionalSecretData != nil { + in, out := &in.AdditionalSecretData, &out.AdditionalSecretData + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Authentication. +func (in *Authentication) DeepCopy() *Authentication { + if in == nil { + return nil + } + out := new(Authentication) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Connection) DeepCopyInto(out *Connection) { + *out = *in + if in.Endpoint != nil { + in, out := &in.Endpoint, &out.Endpoint + *out = new(Endpoint) + (*in).DeepCopyInto(*out) + } + if in.Authentication != nil { + in, out := &in.Authentication, &out.Authentication + *out = new(Authentication) + (*in).DeepCopyInto(*out) + } + if in.AdditionalState != nil { + in, out := &in.AdditionalState, &out.AdditionalState + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Connection. +func (in *Connection) DeepCopy() *Connection { + if in == nil { + return nil + } + out := new(Connection) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Endpoint) DeepCopyInto(out *Endpoint) { + *out = *in + if in.AdditionalConfigData != nil { + in, out := &in.AdditionalConfigData, &out.AdditionalConfigData + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Endpoint. +func (in *Endpoint) DeepCopy() *Endpoint { + if in == nil { + return nil + } + out := new(Endpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectBucket) DeepCopyInto(out *ObjectBucket) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectBucket. +func (in *ObjectBucket) DeepCopy() *ObjectBucket { + if in == nil { + return nil + } + out := new(ObjectBucket) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ObjectBucket) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectBucketClaim) DeepCopyInto(out *ObjectBucketClaim) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectBucketClaim. +func (in *ObjectBucketClaim) DeepCopy() *ObjectBucketClaim { + if in == nil { + return nil + } + out := new(ObjectBucketClaim) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ObjectBucketClaim) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectBucketClaimList) DeepCopyInto(out *ObjectBucketClaimList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ObjectBucketClaim, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectBucketClaimList. +func (in *ObjectBucketClaimList) DeepCopy() *ObjectBucketClaimList { + if in == nil { + return nil + } + out := new(ObjectBucketClaimList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ObjectBucketClaimList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectBucketClaimSpec) DeepCopyInto(out *ObjectBucketClaimSpec) { + *out = *in + if in.AdditionalConfig != nil { + in, out := &in.AdditionalConfig, &out.AdditionalConfig + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectBucketClaimSpec. +func (in *ObjectBucketClaimSpec) DeepCopy() *ObjectBucketClaimSpec { + if in == nil { + return nil + } + out := new(ObjectBucketClaimSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectBucketClaimStatus) DeepCopyInto(out *ObjectBucketClaimStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectBucketClaimStatus. +func (in *ObjectBucketClaimStatus) DeepCopy() *ObjectBucketClaimStatus { + if in == nil { + return nil + } + out := new(ObjectBucketClaimStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectBucketList) DeepCopyInto(out *ObjectBucketList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ObjectBucket, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectBucketList. +func (in *ObjectBucketList) DeepCopy() *ObjectBucketList { + if in == nil { + return nil + } + out := new(ObjectBucketList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ObjectBucketList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectBucketSpec) DeepCopyInto(out *ObjectBucketSpec) { + *out = *in + if in.ReclaimPolicy != nil { + in, out := &in.ReclaimPolicy, &out.ReclaimPolicy + *out = new(v1.PersistentVolumeReclaimPolicy) + **out = **in + } + if in.ClaimRef != nil { + in, out := &in.ClaimRef, &out.ClaimRef + *out = new(v1.ObjectReference) + **out = **in + } + if in.Connection != nil { + in, out := &in.Connection, &out.Connection + *out = new(Connection) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectBucketSpec. +func (in *ObjectBucketSpec) DeepCopy() *ObjectBucketSpec { + if in == nil { + return nil + } + out := new(ObjectBucketSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectBucketStatus) DeepCopyInto(out *ObjectBucketStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectBucketStatus. +func (in *ObjectBucketStatus) DeepCopy() *ObjectBucketStatus { + if in == nil { + return nil + } + out := new(ObjectBucketStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/libopenstorage/secrets/vault/utils/utils.go b/vendor/github.com/libopenstorage/secrets/vault/utils/utils.go index cac8b213d4d..08e570b01d0 100644 --- a/vendor/github.com/libopenstorage/secrets/vault/utils/utils.go +++ b/vendor/github.com/libopenstorage/secrets/vault/utils/utils.go @@ -49,6 +49,7 @@ var ( ErrAuthMethodUnknown = errors.New("unknown auth method") ErrKubernetesRole = errors.New(AuthKubernetesRole + " not set") + ErrInCooldown = errors.New("vault client is in cooldown") ) // IsValidAddr checks address has the correct format. diff --git a/vendor/github.com/libopenstorage/secrets/vault/vault.go b/vendor/github.com/libopenstorage/secrets/vault/vault.go index 15916b7c77d..72b648e17b8 100644 --- a/vendor/github.com/libopenstorage/secrets/vault/vault.go +++ b/vendor/github.com/libopenstorage/secrets/vault/vault.go @@ -5,6 +5,7 @@ import ( "path" "strings" "sync" + "time" "github.com/hashicorp/vault/api" "github.com/libopenstorage/secrets" @@ -13,15 +14,17 @@ import ( ) const ( - Name = secrets.TypeVault - DefaultBackendPath = "secret/" - VaultBackendPathKey = "VAULT_BACKEND_PATH" - VaultBackendKey = "VAULT_BACKEND" - kvVersionKey = "version" - kvDataKey = "data" - kvMetadataKey = "metadata" - kvVersion1 = "kv" - kvVersion2 = "kv-v2" + Name = secrets.TypeVault + DefaultBackendPath = "secret/" + VaultBackendPathKey = "VAULT_BACKEND_PATH" + VaultBackendKey = "VAULT_BACKEND" + VaultCooldownPeriod = "VAULT_COOLDOWN_PERIOD" + kvVersionKey = "version" + kvDataKey = "data" + kvMetadataKey = "metadata" + kvVersion1 = "kv" + kvVersion2 = "kv-v2" + defaultCooldownPeriod = 5 * time.Minute AuthMethodKubernetes = utils.AuthMethodKubernetes AuthMethod = utils.AuthMethod @@ -52,12 +55,14 @@ type vaultSecrets struct { isKvBackendV2 bool autoAuth bool config map[string]interface{} + cooldown time.Time } // These variables are helpful in testing to stub method call from packages var ( - newVaultClient = api.NewClient - isKvV2 = isKvBackendV2 + newVaultClient = api.NewClient + isKvV2 = isKvBackendV2 + confCooldownPeriod time.Duration ) func New( @@ -109,7 +114,7 @@ func New( authMethod = method } - logrus.Infof("Authenticated to Vault with %v\n", authMethod) + logrus.Infof("Will authenticate to Vault via %v", authMethod) backendPath := utils.GetVaultParam(secretConfig, VaultBackendPathKey) if backendPath == "" { @@ -130,6 +135,20 @@ func New( return nil, err } } + + confCooldownPeriod = defaultCooldownPeriod + if cd := utils.GetVaultParam(secretConfig, VaultCooldownPeriod); cd != "" { + if cd == "0" { + logrus.Warnf("cooldown period is disabled via %s=%s", VaultCooldownPeriod, cd) + confCooldownPeriod = 0 + } else if confCooldownPeriod, err = time.ParseDuration(cd); err == nil && confCooldownPeriod > time.Minute { + logrus.Infof("cooldown period is set to %s", confCooldownPeriod) + } else { + return nil, fmt.Errorf("invalid cooldown period: %s=%s", VaultCooldownPeriod, cd) + } + } + logrus.Infof("cooldown period is set to %s", confCooldownPeriod) + return &vaultSecrets{ endpoint: config.Address, namespace: namespace, @@ -261,6 +280,9 @@ func (v *vaultSecrets) ListSecrets() ([]string, error) { } func (v *vaultSecrets) read(path keyPath) (*api.Secret, error) { + if v.isInCooldown() { + return nil, utils.ErrInCooldown + } if v.autoAuth { v.lockClientToken.Lock() defer v.lockClientToken.Unlock() @@ -272,7 +294,7 @@ func (v *vaultSecrets) read(path keyPath) (*api.Secret, error) { secretValue, err := v.lockedRead(path.Path()) if v.isTokenExpired(err) { - if err = v.renewToken(path.Namespace()); err != nil { + if err = v.renewTokenWithCooldown(path.Namespace()); err != nil { return nil, fmt.Errorf("failed to renew token: %s", err) } return v.lockedRead(path.Path()) @@ -281,6 +303,9 @@ func (v *vaultSecrets) read(path keyPath) (*api.Secret, error) { } func (v *vaultSecrets) write(path keyPath, data map[string]interface{}) (*api.Secret, error) { + if v.isInCooldown() { + return nil, utils.ErrInCooldown + } if v.autoAuth { v.lockClientToken.Lock() defer v.lockClientToken.Unlock() @@ -292,7 +317,7 @@ func (v *vaultSecrets) write(path keyPath, data map[string]interface{}) (*api.Se secretValue, err := v.lockedWrite(path.Path(), data) if v.isTokenExpired(err) { - if err = v.renewToken(path.Namespace()); err != nil { + if err = v.renewTokenWithCooldown(path.Namespace()); err != nil { return nil, fmt.Errorf("failed to renew token: %s", err) } return v.lockedWrite(path.Path(), data) @@ -301,6 +326,9 @@ func (v *vaultSecrets) write(path keyPath, data map[string]interface{}) (*api.Se } func (v *vaultSecrets) delete(path keyPath) (*api.Secret, error) { + if v.isInCooldown() { + return nil, utils.ErrInCooldown + } if v.autoAuth { v.lockClientToken.Lock() defer v.lockClientToken.Unlock() @@ -312,7 +340,7 @@ func (v *vaultSecrets) delete(path keyPath) (*api.Secret, error) { secretValue, err := v.lockedDelete(path.Path()) if v.isTokenExpired(err) { - if err = v.renewToken(path.Namespace()); err != nil { + if err = v.renewTokenWithCooldown(path.Namespace()); err != nil { return nil, fmt.Errorf("failed to renew token: %s", err) } return v.lockedDelete(path.Path()) @@ -359,6 +387,50 @@ func (v *vaultSecrets) renewToken(namespace string) error { return nil } +func (v *vaultSecrets) renewTokenWithCooldown(namespace string) error { + if confCooldownPeriod <= 0 { // cooldown is disabled, return immediately + return v.renewToken(namespace) + } else if v.isInCooldown() { + return utils.ErrInCooldown + } + + err := v.renewToken(namespace) + if v.isTokenExpired(err) { + v.setCooldown(confCooldownPeriod) + } else if err == nil { + v.setCooldown(0) // clear cooldown + } + return err +} + +func (v *vaultSecrets) isInCooldown() bool { + if confCooldownPeriod <= 0 { // cooldown is disabled, return immediately + return false + } + v.mu.RLock() + defer v.mu.RUnlock() + if v.cooldown.IsZero() { + return false + } + return time.Now().Before(v.cooldown) +} + +func (v *vaultSecrets) setCooldown(dur time.Duration) { + if confCooldownPeriod <= 0 { // cooldown is disabled, return immediately + return + } + v.mu.Lock() + defer v.mu.Unlock() + if dur > 0 { + v.cooldown = time.Now().Add(dur) + logrus.WithField("nextRetryAt", v.cooldown.Round(100*time.Millisecond)). + Warnf("putting vault client in cooldown for %s", confCooldownPeriod) + } else { + logrus.Debug("clearing vault client cooldown") + v.cooldown = time.Time{} + } +} + func (v *vaultSecrets) isTokenExpired(err error) bool { return err != nil && v.autoAuth && strings.Contains(err.Error(), "permission denied") } @@ -373,7 +445,7 @@ func (v *vaultSecrets) setNamespaceToken(namespace string) error { return nil } - return v.renewToken(namespace) + return v.renewTokenWithCooldown(namespace) } func isKvBackendV2(client *api.Client, backendPath string) (bool, error) { @@ -393,7 +465,7 @@ func isKvBackendV2(client *api.Client, backendPath string) (bool, error) { } } - return false, fmt.Errorf("Secrets engine with mount path '%s' not found", + return false, fmt.Errorf("secrets engine with mount path '%s' not found", backendPath) } diff --git a/vendor/github.com/openshift/api/security/v1/0000_03_security-openshift_01_scc.crd.yaml b/vendor/github.com/openshift/api/security/v1/0000_03_security-openshift_01_scc.crd.yaml index f08d16578a1..a533efbc157 100644 --- a/vendor/github.com/openshift/api/security/v1/0000_03_security-openshift_01_scc.crd.yaml +++ b/vendor/github.com/openshift/api/security/v1/0000_03_security-openshift_01_scc.crd.yaml @@ -16,264 +16,350 @@ spec: singular: securitycontextconstraints scope: Cluster versions: - - additionalPrinterColumns: - - description: Determines if a container can request to be run as privileged - jsonPath: .allowPrivilegedContainer - name: Priv - type: string - - description: A list of capabilities that can be requested to add to the container - jsonPath: .allowedCapabilities - name: Caps - type: string - - description: Strategy that will dictate what labels will be set in the SecurityContext - jsonPath: .seLinuxContext.type - name: SELinux - type: string - - description: Strategy that will dictate what RunAsUser is used in the SecurityContext - jsonPath: .runAsUser.type - name: RunAsUser - type: string - - description: Strategy that will dictate what fs group is used by the SecurityContext - jsonPath: .fsGroup.type - name: FSGroup - type: string - - description: Strategy that will dictate what supplemental groups are used by the SecurityContext - jsonPath: .supplementalGroups.type - name: SupGroup - type: string - - description: Sort order of SCCs - jsonPath: .priority - name: Priority - type: string - - description: Force containers to run with a read only root file system - jsonPath: .readOnlyRootFilesystem - name: ReadOnlyRootFS - type: string - - description: White list of allowed volume plugins - jsonPath: .volumes - name: Volumes - type: string - name: v1 - schema: - openAPIV3Schema: - description: "SecurityContextConstraints governs the ability to make requests that affect the SecurityContext that will be applied to a container. For historical reasons SCC was exposed under the core Kubernetes API group. That exposure is deprecated and will be removed in a future release - users should instead use the security.openshift.io group to manage SecurityContextConstraints. \n Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer)." - type: object - required: - - allowHostDirVolumePlugin - - allowHostIPC - - allowHostNetwork - - allowHostPID - - allowHostPorts - - allowPrivilegedContainer - - allowedCapabilities - - defaultAddCapabilities - - priority - - readOnlyRootFilesystem - - requiredDropCapabilities - - volumes - properties: - allowHostDirVolumePlugin: - description: AllowHostDirVolumePlugin determines if the policy allow containers to use the HostDir volume plugin - type: boolean - allowHostIPC: - description: AllowHostIPC determines if the policy allows host ipc in the containers. - type: boolean - allowHostNetwork: - description: AllowHostNetwork determines if the policy allows the use of HostNetwork in the pod spec. - type: boolean - allowHostPID: - description: AllowHostPID determines if the policy allows host pid in the containers. - type: boolean - allowHostPorts: - description: AllowHostPorts determines if the policy allows host ports in the containers. - type: boolean - allowPrivilegeEscalation: - description: AllowPrivilegeEscalation determines if a pod can request to allow privilege escalation. If unspecified, defaults to true. - type: boolean - nullable: true - allowPrivilegedContainer: - description: AllowPrivilegedContainer determines if a container can request to be run as privileged. - type: boolean - allowedCapabilities: - description: AllowedCapabilities is a list of capabilities that can be requested to add to the container. Capabilities in this field maybe added at the pod author's discretion. You must not list a capability in both AllowedCapabilities and RequiredDropCapabilities. To allow all capabilities you may use '*'. - type: array - items: - description: Capability represent POSIX capabilities type - type: string - nullable: true - allowedFlexVolumes: - description: AllowedFlexVolumes is a whitelist of allowed Flexvolumes. Empty or nil indicates that all Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes is allowed in the "Volumes" field. - type: array - items: - description: AllowedFlexVolume represents a single Flexvolume that is allowed to be used. - type: object - required: - - driver - properties: - driver: - description: Driver is the name of the Flexvolume driver. - type: string - nullable: true - allowedUnsafeSysctls: - description: "AllowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. Kubelet has to whitelist all allowed unsafe sysctls explicitly to avoid rejection. \n Examples: e.g. \"foo/*\" allows \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" allows \"foo.bar\", \"foo.baz\", etc." - type: array - items: - type: string - nullable: true - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - defaultAddCapabilities: - description: DefaultAddCapabilities is the default set of capabilities that will be added to the container unless the pod spec specifically drops the capability. You may not list a capabiility in both DefaultAddCapabilities and RequiredDropCapabilities. - type: array - items: - description: Capability represent POSIX capabilities type - type: string - nullable: true - defaultAllowPrivilegeEscalation: - description: DefaultAllowPrivilegeEscalation controls the default setting for whether a process can gain more privileges than its parent process. - type: boolean - nullable: true - forbiddenSysctls: - description: "ForbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of forbidden sysctls. Single * means all sysctls are forbidden. \n Examples: e.g. \"foo/*\" forbids \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" forbids \"foo.bar\", \"foo.baz\", etc." - type: array - items: - type: string - nullable: true - fsGroup: - description: FSGroup is the strategy that will dictate what fs group is used by the SecurityContext. - type: object - properties: - ranges: - description: Ranges are the allowed ranges of fs groups. If you would like to force a single fs group then supply a single range with the same start and end. - type: array - items: - description: 'IDRange provides a min/max of an allowed range of IDs. TODO: this could be reused for UIDs.' - type: object - properties: - max: - description: Max is the end of the range, inclusive. - type: integer - format: int64 - min: - description: Min is the start of the range, inclusive. - type: integer - format: int64 - type: - description: Type is the strategy that will dictate what FSGroup is used in the SecurityContext. - type: string - nullable: true - groups: - description: The groups that have permission to use this security context constraints - type: array - items: - type: string - nullable: true - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + - additionalPrinterColumns: + - description: Determines if a container can request to be run as privileged + jsonPath: .allowPrivilegedContainer + name: Priv + type: string + - description: A list of capabilities that can be requested to add to the container + jsonPath: .allowedCapabilities + name: Caps + type: string + - description: Strategy that will dictate what labels will be set in the SecurityContext + jsonPath: .seLinuxContext.type + name: SELinux + type: string + - description: Strategy that will dictate what RunAsUser is used in the SecurityContext + jsonPath: .runAsUser.type + name: RunAsUser + type: string + - description: Strategy that will dictate what fs group is used by the SecurityContext + jsonPath: .fsGroup.type + name: FSGroup + type: string + - description: Strategy that will dictate what supplemental groups are used by + the SecurityContext + jsonPath: .supplementalGroups.type + name: SupGroup + type: string + - description: Sort order of SCCs + jsonPath: .priority + name: Priority + type: string + - description: Force containers to run with a read only root file system + jsonPath: .readOnlyRootFilesystem + name: ReadOnlyRootFS + type: string + - description: White list of allowed volume plugins + jsonPath: .volumes + name: Volumes + type: string + name: v1 + schema: + openAPIV3Schema: + description: "SecurityContextConstraints governs the ability to make requests + that affect the SecurityContext that will be applied to a container. For + historical reasons SCC was exposed under the core Kubernetes API group. + That exposure is deprecated and will be removed in a future release - users + should instead use the security.openshift.io group to manage SecurityContextConstraints. + \n Compatibility level 1: Stable within a major release for a minimum of + 12 months or 3 minor releases (whichever is longer)." + properties: + allowHostDirVolumePlugin: + description: AllowHostDirVolumePlugin determines if the policy allow containers + to use the HostDir volume plugin + type: boolean + allowHostIPC: + description: AllowHostIPC determines if the policy allows host ipc in + the containers. + type: boolean + allowHostNetwork: + description: AllowHostNetwork determines if the policy allows the use + of HostNetwork in the pod spec. + type: boolean + allowHostPID: + description: AllowHostPID determines if the policy allows host pid in + the containers. + type: boolean + allowHostPorts: + description: AllowHostPorts determines if the policy allows host ports + in the containers. + type: boolean + allowPrivilegeEscalation: + description: AllowPrivilegeEscalation determines if a pod can request + to allow privilege escalation. If unspecified, defaults to true. + nullable: true + type: boolean + allowPrivilegedContainer: + description: AllowPrivilegedContainer determines if a container can request + to be run as privileged. + type: boolean + allowedCapabilities: + description: AllowedCapabilities is a list of capabilities that can be + requested to add to the container. Capabilities in this field maybe + added at the pod author's discretion. You must not list a capability + in both AllowedCapabilities and RequiredDropCapabilities. To allow all + capabilities you may use '*'. + items: + description: Capability represent POSIX capabilities type type: string - metadata: - type: object - priority: - description: Priority influences the sort order of SCCs when evaluating which SCCs to try first for a given pod request based on access in the Users and Groups fields. The higher the int, the higher priority. An unset value is considered a 0 priority. If scores for multiple SCCs are equal they will be sorted from most restrictive to least restrictive. If both priorities and restrictions are equal the SCCs will be sorted by name. - type: integer - format: int32 - nullable: true - readOnlyRootFilesystem: - description: ReadOnlyRootFilesystem when set to true will force containers to run with a read only root file system. If the container specifically requests to run with a non-read only root file system the SCC should deny the pod. If set to false the container may run with a read only root file system if it wishes but it will not be forced to. - type: boolean - requiredDropCapabilities: - description: RequiredDropCapabilities are the capabilities that will be dropped from the container. These are required to be dropped and cannot be added. - type: array - items: - description: Capability represent POSIX capabilities type - type: string - nullable: true - runAsUser: - description: RunAsUser is the strategy that will dictate what RunAsUser is used in the SecurityContext. - type: object + nullable: true + type: array + allowedFlexVolumes: + description: AllowedFlexVolumes is a whitelist of allowed Flexvolumes. Empty + or nil indicates that all Flexvolumes may be used. This parameter is + effective only when the usage of the Flexvolumes is allowed in the "Volumes" + field. + items: + description: AllowedFlexVolume represents a single Flexvolume that is + allowed to be used. properties: - type: - description: Type is the strategy that will dictate what RunAsUser is used in the SecurityContext. + driver: + description: Driver is the name of the Flexvolume driver. type: string - uid: - description: UID is the user id that containers must run as. Required for the MustRunAs strategy if not using namespace/service account allocated uids. - type: integer - format: int64 - uidRangeMax: - description: UIDRangeMax defines the max value for a strategy that allocates by range. - type: integer - format: int64 - uidRangeMin: - description: UIDRangeMin defines the min value for a strategy that allocates by range. - type: integer - format: int64 - nullable: true - seLinuxContext: - description: SELinuxContext is the strategy that will dictate what labels will be set in the SecurityContext. + required: + - driver type: object - properties: - seLinuxOptions: - description: seLinuxOptions required to run as; required for MustRunAs - type: object + nullable: true + type: array + allowedUnsafeSysctls: + description: "AllowedUnsafeSysctls is a list of explicitly allowed unsafe + sysctls, defaults to none. Each entry is either a plain sysctl name + or ends in \"*\" in which case it is considered as a prefix of allowed + sysctls. Single * means all unsafe sysctls are allowed. Kubelet has + to whitelist all allowed unsafe sysctls explicitly to avoid rejection. + \n Examples: e.g. \"foo/*\" allows \"foo/bar\", \"foo/baz\", etc. e.g. + \"foo.*\" allows \"foo.bar\", \"foo.baz\", etc." + items: + type: string + nullable: true + type: array + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + defaultAddCapabilities: + description: DefaultAddCapabilities is the default set of capabilities + that will be added to the container unless the pod spec specifically + drops the capability. You may not list a capabiility in both DefaultAddCapabilities + and RequiredDropCapabilities. + items: + description: Capability represent POSIX capabilities type + type: string + nullable: true + type: array + defaultAllowPrivilegeEscalation: + description: DefaultAllowPrivilegeEscalation controls the default setting + for whether a process can gain more privileges than its parent process. + nullable: true + type: boolean + forbiddenSysctls: + description: "ForbiddenSysctls is a list of explicitly forbidden sysctls, + defaults to none. Each entry is either a plain sysctl name or ends in + \"*\" in which case it is considered as a prefix of forbidden sysctls. + Single * means all sysctls are forbidden. \n Examples: e.g. \"foo/*\" + forbids \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" forbids \"foo.bar\", + \"foo.baz\", etc." + items: + type: string + nullable: true + type: array + fsGroup: + description: FSGroup is the strategy that will dictate what fs group is + used by the SecurityContext. + nullable: true + properties: + ranges: + description: Ranges are the allowed ranges of fs groups. If you would + like to force a single fs group then supply a single range with + the same start and end. + items: + description: 'IDRange provides a min/max of an allowed range of + IDs. TODO: this could be reused for UIDs.' properties: - level: - description: Level is SELinux level label that applies to the container. - type: string - role: - description: Role is a SELinux role label that applies to the container. - type: string - type: - description: Type is a SELinux type label that applies to the container. - type: string - user: - description: User is a SELinux user label that applies to the container. - type: string - type: - description: Type is the strategy that will dictate what SELinux context is used in the SecurityContext. - type: string - nullable: true - seccompProfiles: - description: "SeccompProfiles lists the allowed profiles that may be set for the pod or container's seccomp annotations. An unset (nil) or empty value means that no profiles may be specifid by the pod or container.\tThe wildcard '*' may be used to allow all profiles. When used to generate a value for a pod the first non-wildcard profile will be used as the default." - type: array - items: + max: + description: Max is the end of the range, inclusive. + format: int64 + type: integer + min: + description: Min is the start of the range, inclusive. + format: int64 + type: integer + type: object + type: array + type: + description: Type is the strategy that will dictate what FSGroup is + used in the SecurityContext. type: string - nullable: true - supplementalGroups: - description: SupplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext. - type: object - properties: - ranges: - description: Ranges are the allowed ranges of supplemental groups. If you would like to force a single supplemental group then supply a single range with the same start and end. - type: array - items: - description: 'IDRange provides a min/max of an allowed range of IDs. TODO: this could be reused for UIDs.' - type: object - properties: - max: - description: Max is the end of the range, inclusive. - type: integer - format: int64 - min: - description: Min is the start of the range, inclusive. - type: integer - format: int64 - type: - description: Type is the strategy that will dictate what supplemental groups is used in the SecurityContext. - type: string - nullable: true - users: - description: The users who have permissions to use this security context constraints - type: array - items: + type: object + groups: + description: The groups that have permission to use this security context + constraints + items: + type: string + nullable: true + type: array + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + priority: + description: Priority influences the sort order of SCCs when evaluating + which SCCs to try first for a given pod request based on access in the + Users and Groups fields. The higher the int, the higher priority. An + unset value is considered a 0 priority. If scores for multiple SCCs + are equal they will be sorted from most restrictive to least restrictive. + If both priorities and restrictions are equal the SCCs will be sorted + by name. + format: int32 + nullable: true + type: integer + readOnlyRootFilesystem: + description: ReadOnlyRootFilesystem when set to true will force containers + to run with a read only root file system. If the container specifically + requests to run with a non-read only root file system the SCC should + deny the pod. If set to false the container may run with a read only + root file system if it wishes but it will not be forced to. + type: boolean + requiredDropCapabilities: + description: RequiredDropCapabilities are the capabilities that will be + dropped from the container. These are required to be dropped and cannot + be added. + items: + description: Capability represent POSIX capabilities type + type: string + nullable: true + type: array + runAsUser: + description: RunAsUser is the strategy that will dictate what RunAsUser + is used in the SecurityContext. + nullable: true + properties: + type: + description: Type is the strategy that will dictate what RunAsUser + is used in the SecurityContext. type: string - nullable: true - volumes: - description: Volumes is a white list of allowed volume plugins. FSType corresponds directly with the field names of a VolumeSource (azureFile, configMap, emptyDir). To allow all volumes you may use "*". To allow no volumes, set to ["none"]. - type: array - items: - description: FS Type gives strong typing to different file systems that are used by volumes. + uid: + description: UID is the user id that containers must run as. Required + for the MustRunAs strategy if not using namespace/service account + allocated uids. + format: int64 + type: integer + uidRangeMax: + description: UIDRangeMax defines the max value for a strategy that + allocates by range. + format: int64 + type: integer + uidRangeMin: + description: UIDRangeMin defines the min value for a strategy that + allocates by range. + format: int64 + type: integer + type: object + seLinuxContext: + description: SELinuxContext is the strategy that will dictate what labels + will be set in the SecurityContext. + nullable: true + properties: + seLinuxOptions: + description: seLinuxOptions required to run as; required for MustRunAs + properties: + level: + description: Level is SELinux level label that applies to the + container. + type: string + role: + description: Role is a SELinux role label that applies to the + container. + type: string + type: + description: Type is a SELinux type label that applies to the + container. + type: string + user: + description: User is a SELinux user label that applies to the + container. + type: string + type: object + type: + description: Type is the strategy that will dictate what SELinux context + is used in the SecurityContext. type: string - nullable: true - served: true - storage: true + type: object + seccompProfiles: + description: "SeccompProfiles lists the allowed profiles that may be set + for the pod or container's seccomp annotations. An unset (nil) or empty + value means that no profiles may be specifid by the pod or container.\tThe + wildcard '*' may be used to allow all profiles. When used to generate + a value for a pod the first non-wildcard profile will be used as the + default." + items: + type: string + nullable: true + type: array + supplementalGroups: + description: SupplementalGroups is the strategy that will dictate what + supplemental groups are used by the SecurityContext. + nullable: true + properties: + ranges: + description: Ranges are the allowed ranges of supplemental groups. If + you would like to force a single supplemental group then supply + a single range with the same start and end. + items: + description: 'IDRange provides a min/max of an allowed range of + IDs. TODO: this could be reused for UIDs.' + properties: + max: + description: Max is the end of the range, inclusive. + format: int64 + type: integer + min: + description: Min is the start of the range, inclusive. + format: int64 + type: integer + type: object + type: array + type: + description: Type is the strategy that will dictate what supplemental + groups is used in the SecurityContext. + type: string + type: object + users: + description: The users who have permissions to use this security context + constraints + items: + type: string + nullable: true + type: array + volumes: + description: Volumes is a white list of allowed volume plugins. FSType + corresponds directly with the field names of a VolumeSource (azureFile, + configMap, emptyDir). To allow all volumes you may use "*". To allow + no volumes, set to ["none"]. + items: + description: FS Type gives strong typing to different file systems that + are used by volumes. + type: string + nullable: true + type: array + required: + - allowHostDirVolumePlugin + - allowHostIPC + - allowHostNetwork + - allowHostPID + - allowHostPorts + - allowPrivilegedContainer + - allowedCapabilities + - defaultAddCapabilities + - priority + - readOnlyRootFilesystem + - requiredDropCapabilities + - volumes + type: object + served: true + storage: true diff --git a/vendor/github.com/rook/kubectl-rook-ceph/LICENSE b/vendor/github.com/rook/kubectl-rook-ceph/LICENSE new file mode 100644 index 00000000000..8e8487438ac --- /dev/null +++ b/vendor/github.com/rook/kubectl-rook-ceph/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 The Rook Authors. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/context.go b/vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/context.go new file mode 100644 index 00000000000..9a8b287fe4b --- /dev/null +++ b/vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/context.go @@ -0,0 +1,39 @@ +/* +Copyright 2023 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package k8sutil + +import ( + "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + + rookclient "github.com/rook/rook/pkg/client/clientset/versioned" +) + +type Clientsets struct { + // The Kubernetes config used for these client sets + KubeConfig *rest.Config + + // Kube is a connection to the core Kubernetes API + Kube kubernetes.Interface + + // Rook is a typed connection to the rook API + Rook rookclient.Interface + + // Dynamic is used for manage dynamic resources + Dynamic dynamic.Interface +} diff --git a/vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/dynamic.go b/vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/dynamic.go new file mode 100644 index 00000000000..3acd7e07593 --- /dev/null +++ b/vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/dynamic.go @@ -0,0 +1,146 @@ +/* +Copyright 2023 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package k8sutil + +import ( + "context" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" +) + +func (c *Clientsets) ListResourcesDynamically( + ctx context.Context, + group string, + version string, + resource string, + namespace string, +) ([]unstructured.Unstructured, error) { + resourceId := schema.GroupVersionResource{ + Group: group, + Version: version, + Resource: resource, + } + + list, err := c.Dynamic.Resource(resourceId).Namespace(namespace). + List(ctx, metav1.ListOptions{}) + + if err != nil { + return nil, err + } + + return list.Items, nil +} + +func (c *Clientsets) DeleteResourcesDynamically( + ctx context.Context, + group string, + version string, + resource string, + namespace string, + resourceName string, +) error { + + resourceId := schema.GroupVersionResource{ + Group: group, + Version: version, + Resource: resource, + } + err := c.Dynamic.Resource(resourceId).Namespace(namespace). + Delete(ctx, resourceName, metav1.DeleteOptions{}) + + if err != nil { + return err + } + return nil +} + +func (c *Clientsets) PatchResourcesDynamically( + ctx context.Context, + group string, + version string, + resource string, + namespace string, + resourceName string, + pt types.PatchType, + data []byte, +) error { + + resourceId := schema.GroupVersionResource{ + Group: group, + Version: version, + Resource: resource, + } + + _, err := c.Dynamic.Resource(resourceId).Namespace(namespace). + Patch(ctx, resourceName, pt, data, metav1.PatchOptions{}) + + if err != nil { + return err + } + return nil +} + +func (c *Clientsets) GetResourcesDynamically( + ctx context.Context, + group string, + version string, + resource string, + name string, + namespace string, +) (*unstructured.Unstructured, error) { + resourceId := schema.GroupVersionResource{ + Group: group, + Version: version, + Resource: resource, + } + + item, err := c.Dynamic.Resource(resourceId).Namespace(namespace). + Get(ctx, name, metav1.GetOptions{}) + + if err != nil { + return nil, err + } + + return item, nil +} + +func (c *Clientsets) CreateResourcesDynamically( + ctx context.Context, + group string, + version string, + resource string, + name *unstructured.Unstructured, + namespace string, +) (*unstructured.Unstructured, error) { + resourceId := schema.GroupVersionResource{ + Group: group, + Version: version, + Resource: resource, + } + + item, err := c.Dynamic.Resource(resourceId).Namespace(namespace). + Create(ctx, name, metav1.CreateOptions{}) + + if err != nil { + return nil, err + } + + return item, nil +} diff --git a/vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/interface.go b/vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/interface.go new file mode 100644 index 00000000000..9e7eccccd0d --- /dev/null +++ b/vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/interface.go @@ -0,0 +1,33 @@ +/* +Copyright 2023 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package k8sutil + +import ( + "context" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" +) + +//go:generate mockgen -package=k8sutil --build_flags=--mod=mod -destination=mocks.go github.com/rook/kubectl-rook-ceph/pkg/k8sutil ClientsetsInterface +type ClientsetsInterface interface { + CreateResourcesDynamically(ctx context.Context, group string, version string, resource string, name *unstructured.Unstructured, namespace string) (*unstructured.Unstructured, error) + ListResourcesDynamically(ctx context.Context, group string, version string, resource string, namespace string) ([]unstructured.Unstructured, error) + GetResourcesDynamically(ctx context.Context, group string, version string, resource string, name string, namespace string) (*unstructured.Unstructured, error) + DeleteResourcesDynamically(ctx context.Context, group string, version string, resource string, namespace string, resourceName string) error + PatchResourcesDynamically(ctx context.Context, group string, version string, resource string, namespace string, resourceName string, pt types.PatchType, data []byte) error +} diff --git a/vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/k8sutil.go b/vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/k8sutil.go new file mode 100644 index 00000000000..c0b70a41fcf --- /dev/null +++ b/vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/k8sutil.go @@ -0,0 +1,124 @@ +/* +Copyright 2023 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package k8sutil + +import ( + "context" + "fmt" + "time" + + "github.com/rook/kubectl-rook-ceph/pkg/logging" + + appsv1 "k8s.io/api/apps/v1" + autoscalingv1 "k8s.io/api/autoscaling/v1" + corev1 "k8s.io/api/core/v1" + k8sErrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes" +) + +func RestartDeployment(ctx context.Context, k8sclientset kubernetes.Interface, namespace, deploymentName string) { + deploymentsClient := k8sclientset.AppsV1().Deployments(namespace) + data := fmt.Sprintf(`{"spec": {"template": {"metadata": {"annotations": {"kubectl.kubernetes.io/restartedAt": "%s"}}}}}`, time.Now().String()) + _, err := deploymentsClient.Patch(ctx, deploymentName, types.StrategicMergePatchType, []byte(data), v1.PatchOptions{}) + if err != nil { + logging.Error(fmt.Errorf("Failed to delete deployment %s: %v", deploymentName, err)) + } + + logging.Info("deployment.apps/%s restarted\n", deploymentName) +} + +func WaitForPodToRun(ctx context.Context, k8sclientset kubernetes.Interface, namespace, labelSelector string) (corev1.Pod, error) { + opts := v1.ListOptions{LabelSelector: labelSelector, FieldSelector: "status.phase=Running"} + for i := 0; i < 60; i++ { + pod, err := k8sclientset.CoreV1().Pods(namespace).List(ctx, opts) + if err != nil { + return corev1.Pod{}, fmt.Errorf("failed to list pods with labels matching %s", labelSelector) + } + if len(pod.Items) != 0 { + if pod.Items[0].Status.Phase == corev1.PodRunning && pod.Items[0].DeletionTimestamp.IsZero() { + return pod.Items[0], nil + } + } + + logging.Info("waiting for pod with label %q in namespace %q to be running", labelSelector, namespace) + time.Sleep(time.Second * 5) + } + + return corev1.Pod{}, fmt.Errorf("No pod with labels matching %s", labelSelector) +} + +func UpdateConfigMap(ctx context.Context, k8sclientset kubernetes.Interface, namespace, configMapName, key, value string) { + cm, err := k8sclientset.CoreV1().ConfigMaps(namespace).Get(ctx, configMapName, v1.GetOptions{}) + if err != nil { + logging.Fatal(err) + } + + if cm.Data == nil { + cm.Data = map[string]string{} + } + + cm.Data[key] = value + _, err = k8sclientset.CoreV1().ConfigMaps(namespace).Update(ctx, cm, v1.UpdateOptions{}) + if err != nil { + logging.Fatal(err) + } + + logging.Info("configmap/%s patched\n", configMapName) +} + +func SetDeploymentScale(ctx context.Context, k8sclientset kubernetes.Interface, namespace, deploymentName string, scaleCount int) error { + scale := &autoscalingv1.Scale{ + ObjectMeta: v1.ObjectMeta{ + Name: deploymentName, + Namespace: namespace, + }, + Spec: autoscalingv1.ScaleSpec{ + Replicas: int32(scaleCount), + }, + } + _, err := k8sclientset.AppsV1().Deployments(namespace).UpdateScale(ctx, deploymentName, scale, v1.UpdateOptions{}) + if err != nil { + return fmt.Errorf("failed to update scale of deployment %s. %v\n", deploymentName, err) + } + return nil +} + +func GetDeployment(ctx context.Context, k8sclientset kubernetes.Interface, clusterNamespace, deploymentName string) (*appsv1.Deployment, error) { + logging.Info("fetching the deployment %s to be running\n", deploymentName) + deployment, err := k8sclientset.AppsV1().Deployments(clusterNamespace).Get(ctx, deploymentName, v1.GetOptions{}) + if err != nil { + return nil, err + } + + logging.Info("deployment %s exists\n", deploymentName) + return deployment, nil +} + +func DeleteDeployment(ctx context.Context, k8sclientset kubernetes.Interface, clusterNamespace string, deployment string) { + logging.Info("removing deployment %s", deployment) + + err := k8sclientset.AppsV1().Deployments(clusterNamespace).Delete(ctx, deployment, v1.DeleteOptions{}) + if err != nil { + if k8sErrors.IsNotFound(err) { + logging.Info("the server could not find the requested deployment: %s", deployment) + return + } + logging.Fatal(err) + } +} diff --git a/vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/mocks.go b/vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/mocks.go new file mode 100644 index 00000000000..8fa25132a31 --- /dev/null +++ b/vendor/github.com/rook/kubectl-rook-ceph/pkg/k8sutil/mocks.go @@ -0,0 +1,110 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/rook/kubectl-rook-ceph/pkg/k8sutil (interfaces: ClientsetsInterface) + +// Package k8sutil is a generated GoMock package. +package k8sutil + +import ( + context "context" + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + types "k8s.io/apimachinery/pkg/types" +) + +// MockClientsetsInterface is a mock of ClientsetsInterface interface. +type MockClientsetsInterface struct { + ctrl *gomock.Controller + recorder *MockClientsetsInterfaceMockRecorder +} + +// MockClientsetsInterfaceMockRecorder is the mock recorder for MockClientsetsInterface. +type MockClientsetsInterfaceMockRecorder struct { + mock *MockClientsetsInterface +} + +// NewMockClientsetsInterface creates a new mock instance. +func NewMockClientsetsInterface(ctrl *gomock.Controller) *MockClientsetsInterface { + mock := &MockClientsetsInterface{ctrl: ctrl} + mock.recorder = &MockClientsetsInterfaceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockClientsetsInterface) EXPECT() *MockClientsetsInterfaceMockRecorder { + return m.recorder +} + +// CreateResourcesDynamically mocks base method. +func (m *MockClientsetsInterface) CreateResourcesDynamically(arg0 context.Context, arg1, arg2, arg3 string, arg4 *unstructured.Unstructured, arg5 string) (*unstructured.Unstructured, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateResourcesDynamically", arg0, arg1, arg2, arg3, arg4, arg5) + ret0, _ := ret[0].(*unstructured.Unstructured) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateResourcesDynamically indicates an expected call of CreateResourcesDynamically. +func (mr *MockClientsetsInterfaceMockRecorder) CreateResourcesDynamically(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateResourcesDynamically", reflect.TypeOf((*MockClientsetsInterface)(nil).CreateResourcesDynamically), arg0, arg1, arg2, arg3, arg4, arg5) +} + +// DeleteResourcesDynamically mocks base method. +func (m *MockClientsetsInterface) DeleteResourcesDynamically(arg0 context.Context, arg1, arg2, arg3, arg4, arg5 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteResourcesDynamically", arg0, arg1, arg2, arg3, arg4, arg5) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteResourcesDynamically indicates an expected call of DeleteResourcesDynamically. +func (mr *MockClientsetsInterfaceMockRecorder) DeleteResourcesDynamically(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteResourcesDynamically", reflect.TypeOf((*MockClientsetsInterface)(nil).DeleteResourcesDynamically), arg0, arg1, arg2, arg3, arg4, arg5) +} + +// GetResourcesDynamically mocks base method. +func (m *MockClientsetsInterface) GetResourcesDynamically(arg0 context.Context, arg1, arg2, arg3, arg4, arg5 string) (*unstructured.Unstructured, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetResourcesDynamically", arg0, arg1, arg2, arg3, arg4, arg5) + ret0, _ := ret[0].(*unstructured.Unstructured) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetResourcesDynamically indicates an expected call of GetResourcesDynamically. +func (mr *MockClientsetsInterfaceMockRecorder) GetResourcesDynamically(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetResourcesDynamically", reflect.TypeOf((*MockClientsetsInterface)(nil).GetResourcesDynamically), arg0, arg1, arg2, arg3, arg4, arg5) +} + +// ListResourcesDynamically mocks base method. +func (m *MockClientsetsInterface) ListResourcesDynamically(arg0 context.Context, arg1, arg2, arg3, arg4 string) ([]unstructured.Unstructured, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListResourcesDynamically", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].([]unstructured.Unstructured) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListResourcesDynamically indicates an expected call of ListResourcesDynamically. +func (mr *MockClientsetsInterfaceMockRecorder) ListResourcesDynamically(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourcesDynamically", reflect.TypeOf((*MockClientsetsInterface)(nil).ListResourcesDynamically), arg0, arg1, arg2, arg3, arg4) +} + +// PatchResourcesDynamically mocks base method. +func (m *MockClientsetsInterface) PatchResourcesDynamically(arg0 context.Context, arg1, arg2, arg3, arg4, arg5 string, arg6 types.PatchType, arg7 []byte) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PatchResourcesDynamically", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + ret0, _ := ret[0].(error) + return ret0 +} + +// PatchResourcesDynamically indicates an expected call of PatchResourcesDynamically. +func (mr *MockClientsetsInterfaceMockRecorder) PatchResourcesDynamically(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PatchResourcesDynamically", reflect.TypeOf((*MockClientsetsInterface)(nil).PatchResourcesDynamically), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +} diff --git a/vendor/github.com/rook/kubectl-rook-ceph/pkg/logging/log.go b/vendor/github.com/rook/kubectl-rook-ceph/pkg/logging/log.go new file mode 100644 index 00000000000..f39735f7364 --- /dev/null +++ b/vendor/github.com/rook/kubectl-rook-ceph/pkg/logging/log.go @@ -0,0 +1,56 @@ +/* +Copyright 2023 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package logging + +import ( + "fmt" + "os" + + "github.com/fatih/color" +) + +func Info(output string, args ...interface{}) { + blue := color.New(color.FgBlue).SprintFunc() + if output != "" { + fmt.Fprintf(os.Stderr, blue("Info: ")) + fmt.Fprintf(os.Stderr, output, args...) + } + + fmt.Fprintf(os.Stderr, "\n") +} + +func Warning(output string, args ...interface{}) { + yellow := color.New(color.FgYellow).SprintFunc() + fmt.Fprintf(os.Stderr, yellow("Warning: ")) + fmt.Fprintf(os.Stderr, output, args...) + fmt.Fprintf(os.Stderr, "\n") +} + +func Error(err error, args ...interface{}) { + red := color.New(color.FgRed).SprintFunc() + fmt.Fprintf(os.Stderr, red("Error: ")) + fmt.Fprintf(os.Stderr, err.Error(), args...) + fmt.Fprintf(os.Stderr, "\n") +} + +func Fatal(err error, args ...interface{}) { + red := color.New(color.FgRed).SprintFunc() + fmt.Fprintf(os.Stderr, red("Error: ")) + fmt.Fprintf(os.Stderr, err.Error(), args...) + fmt.Fprintf(os.Stderr, "\n") + os.Exit(1) +} diff --git a/vendor/github.com/rook/rook/LICENSE b/vendor/github.com/rook/rook/LICENSE new file mode 100644 index 00000000000..8e8487438ac --- /dev/null +++ b/vendor/github.com/rook/rook/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 The Rook Authors. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/rook/rook/pkg/apis/LICENSE b/vendor/github.com/rook/rook/pkg/apis/LICENSE new file mode 100644 index 00000000000..8e8487438ac --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 The Rook Authors. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/register.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/register.go new file mode 100644 index 00000000000..d722c3836e8 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/register.go @@ -0,0 +1,5 @@ +package cephrookio + +const ( + CustomResourceGroupName = "ceph.rook.io" +) diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/annotations.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/annotations.go new file mode 100644 index 00000000000..10b8f407ce6 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/annotations.go @@ -0,0 +1,108 @@ +/* +Copyright 2019 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// AnnotationsSpec is the main spec annotation for all daemons +// +kubebuilder:pruning:PreserveUnknownFields +// +nullable +type AnnotationsSpec map[KeyType]Annotations + +// Annotations are annotations +type Annotations map[string]string + +func (a AnnotationsSpec) All() Annotations { + return a[KeyAll] +} + +// GetMgrAnnotations returns the Annotations for the MGR service +func GetMgrAnnotations(a AnnotationsSpec) Annotations { + return mergeAllAnnotationsWithKey(a, KeyMgr) +} + +// GetMonAnnotations returns the Annotations for the MON service +func GetMonAnnotations(a AnnotationsSpec) Annotations { + return mergeAllAnnotationsWithKey(a, KeyMon) +} + +// GetKeyRotationAnnotations returns the annotations for the key rotation job +func GetKeyRotationAnnotations(a AnnotationsSpec) Annotations { + return mergeAllAnnotationsWithKey(a, KeyRotation) +} + +// GetOSDPrepareAnnotations returns the annotations for the OSD service +func GetOSDPrepareAnnotations(a AnnotationsSpec) Annotations { + return mergeAllAnnotationsWithKey(a, KeyOSDPrepare) +} + +// GetOSDAnnotations returns the annotations for the OSD service +func GetOSDAnnotations(a AnnotationsSpec) Annotations { + return mergeAllAnnotationsWithKey(a, KeyOSD) +} + +// GetCleanupAnnotations returns the Annotations for the cleanup job +func GetCleanupAnnotations(a AnnotationsSpec) Annotations { + return mergeAllAnnotationsWithKey(a, KeyCleanup) +} + +// GetCephExporterAnnotations returns the Annotations for the MGR service +func GetCephExporterAnnotations(a AnnotationsSpec) Annotations { + return mergeAllAnnotationsWithKey(a, KeyCephExporter) +} + +func GetClusterMetadataAnnotations(a AnnotationsSpec) Annotations { + return a[KeyClusterMetadata] +} + +func mergeAllAnnotationsWithKey(a AnnotationsSpec, name KeyType) Annotations { + all := a.All() + if all != nil { + return all.Merge(a[name]) + } + return a[name] +} + +// ApplyToObjectMeta adds annotations to object meta unless the keys are already defined. +func (a Annotations) ApplyToObjectMeta(t *metav1.ObjectMeta) { + if t.Annotations == nil { + t.Annotations = map[string]string{} + } + for k, v := range a { + if _, ok := t.Annotations[k]; !ok { + t.Annotations[k] = v + } + } +} + +// Merge returns an Annotations which results from merging the attributes of the +// original Annotations with the attributes of the supplied one. The supplied +// Annotation attributes will override the original ones if defined. +func (a Annotations) Merge(with map[string]string) Annotations { + ret := a + if ret == nil { + ret = map[string]string{} + } + for k, v := range with { + if _, ok := ret[k]; !ok { + ret[k] = v + } + } + return ret +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/cleanup.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/cleanup.go new file mode 100644 index 00000000000..e17e82aeec6 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/cleanup.go @@ -0,0 +1,47 @@ +/* +Copyright 2020 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +    http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +const ( + // SanitizeDataSourceZero uses /dev/zero as sanitize source + SanitizeDataSourceZero SanitizeDataSourceProperty = "zero" + + // SanitizeDataSourceRandom uses `shred's default entropy source + SanitizeDataSourceRandom SanitizeDataSourceProperty = "random" + + // SanitizeMethodComplete will sanitize everything on the disk + SanitizeMethodComplete SanitizeMethodProperty = "complete" + + // SanitizeMethodQuick will sanitize metadata only on the disk + SanitizeMethodQuick SanitizeMethodProperty = "quick" + + // DeleteDataDirOnHostsConfirmation represents the validation to destroy dataDirHostPath + DeleteDataDirOnHostsConfirmation CleanupConfirmationProperty = "yes-really-destroy-data" +) + +// HasDataDirCleanPolicy returns whether the cluster has a data dir policy +func (c *CleanupPolicySpec) HasDataDirCleanPolicy() bool { + return c.Confirmation == DeleteDataDirOnHostsConfirmation +} + +func (c *SanitizeMethodProperty) String() string { + return string(*c) +} + +func (c *SanitizeDataSourceProperty) String() string { + return string(*c) +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/cluster.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/cluster.go new file mode 100644 index 00000000000..615ffc4ae06 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/cluster.go @@ -0,0 +1,46 @@ +/* +Copyright 2020 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +// RequireMsgr2 checks if the network settings require the msgr2 protocol +func (c *ClusterSpec) RequireMsgr2() bool { + if c.Network.Connections == nil { + return false + } + if c.Network.Connections.RequireMsgr2 { + return true + } + if c.Network.Connections.Compression != nil && c.Network.Connections.Compression.Enabled { + return true + } + if c.Network.Connections.Encryption != nil && c.Network.Connections.Encryption.Enabled { + return true + } + return false +} + +func (c *ClusterSpec) IsStretchCluster() bool { + return c.Mon.StretchCluster != nil && len(c.Mon.StretchCluster.Zones) > 0 +} + +func (c *ClusterSpec) ZonesRequired() bool { + return c.IsStretchCluster() || len(c.Mon.Zones) > 0 +} + +func (c *CephCluster) GetStatusConditions() *[]Condition { + return &c.Status.Conditions +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/doc.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/doc.go new file mode 100644 index 00000000000..b8774f976ef --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2018 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +    http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package,register + +// Package v1 is the v1 version of the API. +// +groupName=ceph.rook.io +package v1 diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/filesystem.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/filesystem.go new file mode 100644 index 00000000000..d5128ec11da --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/filesystem.go @@ -0,0 +1,21 @@ +/* +Copyright 2021 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +    http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +func (c *CephFilesystem) GetStatusConditions() *[]Condition { + return &c.Status.Conditions +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/keys.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/keys.go new file mode 100644 index 00000000000..72e18b30fa6 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/keys.go @@ -0,0 +1,34 @@ +/* +Copyright 2018 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +    http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +const ( + KeyAll = "all" + KeyMds KeyType = "mds" + KeyRgw KeyType = "rgw" + KeyMon KeyType = "mon" + KeyMonArbiter KeyType = "arbiter" + KeyMgr KeyType = "mgr" + KeyOSDPrepare KeyType = "prepareosd" + KeyRotation KeyType = "keyrotation" + KeyOSD KeyType = "osd" + KeyCleanup KeyType = "cleanup" + KeyMonitoring KeyType = "monitoring" + KeyCrashCollector KeyType = "crashcollector" + KeyClusterMetadata KeyType = "clusterMetadata" + KeyCephExporter KeyType = "exporter" +) diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/labels.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/labels.go new file mode 100644 index 00000000000..43a3018b2f5 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/labels.go @@ -0,0 +1,131 @@ +/* +Copyright 2019 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + // SkipReconcileLabelKey is a label indicating that the pod should not be reconciled + SkipReconcileLabelKey = "ceph.rook.io/do-not-reconcile" +) + +// LabelsSpec is the main spec label for all daemons +type LabelsSpec map[KeyType]Labels + +// KeyType type safety +type KeyType string + +// Labels are label for a given daemons +type Labels map[string]string + +func (a LabelsSpec) All() Labels { + return a[KeyAll] +} + +// GetMgrLabels returns the Labels for the MGR service +func GetMgrLabels(a LabelsSpec) Labels { + return mergeAllLabelsWithKey(a, KeyMgr) +} + +// GetMonLabels returns the Labels for the MON service +func GetMonLabels(a LabelsSpec) Labels { + return mergeAllLabelsWithKey(a, KeyMon) +} + +// GetKeyRotationLabels returns labels for the key Rotation job +func GetKeyRotationLabels(a LabelsSpec) Labels { + return mergeAllLabelsWithKey(a, KeyRotation) +} + +// GetOSDPrepareLabels returns the Labels for the OSD prepare job +func GetOSDPrepareLabels(a LabelsSpec) Labels { + return mergeAllLabelsWithKey(a, KeyOSDPrepare) +} + +// GetOSDLabels returns the Labels for the OSD service +func GetOSDLabels(a LabelsSpec) Labels { + return mergeAllLabelsWithKey(a, KeyOSD) +} + +// GetCleanupLabels returns the Labels for the cleanup job +func GetCleanupLabels(a LabelsSpec) Labels { + return mergeAllLabelsWithKey(a, KeyCleanup) +} + +// GetMonitoringLabels returns the Labels for monitoring resources +func GetMonitoringLabels(a LabelsSpec) Labels { + return mergeAllLabelsWithKey(a, KeyMonitoring) +} + +// GetCrashCollectorLabels returns the Labels for the crash collector resources +func GetCrashCollectorLabels(a LabelsSpec) Labels { + return mergeAllLabelsWithKey(a, KeyCrashCollector) +} + +func GetCephExporterLabels(a LabelsSpec) Labels { + return mergeAllLabelsWithKey(a, KeyCephExporter) +} + +func mergeAllLabelsWithKey(a LabelsSpec, name KeyType) Labels { + all := a.All() + if all != nil { + return all.Merge(a[name]) + } + return a[name] +} + +// ApplyToObjectMeta adds labels to object meta unless the keys are already defined. +func (a Labels) ApplyToObjectMeta(t *metav1.ObjectMeta) { + if t.Labels == nil { + t.Labels = map[string]string{} + } + for k, v := range a { + if _, ok := t.Labels[k]; !ok { + t.Labels[k] = v + } + } +} + +// OverwriteApplyToObjectMeta adds labels to object meta, overwriting keys that are already defined. +func (a Labels) OverwriteApplyToObjectMeta(t *metav1.ObjectMeta) { + if t.Labels == nil { + t.Labels = map[string]string{} + } + for k, v := range a { + t.Labels[k] = v + } +} + +// Merge returns a Labels which results from merging the attributes of the +// original Labels with the attributes of the supplied one. The supplied +// Labels attributes will override the original ones if defined. +func (a Labels) Merge(with Labels) Labels { + ret := Labels{} + for k, v := range a { + if _, ok := ret[k]; !ok { + ret[k] = v + } + } + for k, v := range with { + if _, ok := ret[k]; !ok { + ret[k] = v + } + } + return ret +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/mirror.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/mirror.go new file mode 100644 index 00000000000..205aad78cd0 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/mirror.go @@ -0,0 +1,26 @@ +/* +Copyright 2020 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +    http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +// HasPeers returns whether the RBD mirror daemon has peer and should connect to it +func (m *MirroringPeerSpec) HasPeers() bool { + return len(m.SecretNames) != 0 +} + +func (m *FSMirroringSpec) SnapShotScheduleEnabled() bool { + return len(m.SnapshotSchedules) != 0 +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/network.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/network.go new file mode 100644 index 00000000000..6abd842ee54 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/network.go @@ -0,0 +1,175 @@ +/* +Copyright 2019 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +    http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "encoding/json" + "fmt" + "net" + "strings" + + nadv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" + nadutils "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils" + "github.com/pkg/errors" +) + +// IsMultus get whether to use multus network provider +func (n *NetworkSpec) IsMultus() bool { + return n.Provider == NetworkProviderMultus +} + +// IsHost get whether to use host network provider. This method also preserve +// compatibility with the old HostNetwork field. +func (n *NetworkSpec) IsHost() bool { + return (n.HostNetwork && n.Provider == NetworkProviderDefault) || n.Provider == NetworkProviderHost +} + +func ValidateNetworkSpec(clusterNamespace string, spec NetworkSpec) error { + if spec.IsMultus() { + if len(spec.Selectors) == 0 { + return errors.Errorf("at least one network selector must be specified when using the %q network provider", NetworkProviderMultus) + } + + if _, err := spec.GetNetworkSelection(clusterNamespace, CephNetworkPublic); err != nil { + return errors.Wrap(err, "ceph public network selector provided for multus is invalid") + } + if _, err := spec.GetNetworkSelection(clusterNamespace, CephNetworkCluster); err != nil { + return errors.Wrap(err, "ceph cluster network selector provided for multus is invalid") + } + } + + if !spec.AddressRanges.IsEmpty() { + if !spec.IsMultus() && !spec.IsHost() { + // TODO: be sure to update docs that AddressRanges can be specified for host networking as + // well as multus so that the override configmap doesn't need to be set + return errors.Errorf("network ranges can only be specified for %q and %q network providers", NetworkProviderHost, NetworkProviderMultus) + } + if spec.IsMultus() { + if len(spec.AddressRanges.Public) > 0 && !spec.NetworkHasSelection(CephNetworkPublic) { + return errors.Errorf("public address range can only be specified for multus if there is a public network selection") + } + if len(spec.AddressRanges.Cluster) > 0 && !spec.NetworkHasSelection(CephNetworkCluster) { + return errors.Errorf("cluster address range can only be specified for multus if there is a cluster network selection") + } + } + } + + if err := spec.AddressRanges.Validate(); err != nil { + return err + } + + return nil +} + +func ValidateNetworkSpecUpdate(clusterNamespace string, oldSpec, newSpec NetworkSpec) error { + // Allow an attempt to enable or disable host networking, but not other provider changes + oldProvider := oldSpec.Provider + newProvider := newSpec.Provider + if oldProvider != newProvider && oldProvider != "host" && newProvider != "host" { + return errors.Errorf("invalid update: network provider change from %q to %q is not allowed", oldProvider, newProvider) + } + + return ValidateNetworkSpec(clusterNamespace, newSpec) +} + +// NetworkHasSelection returns true if the given Ceph network has a selection. +func (n *NetworkSpec) NetworkHasSelection(network CephNetworkType) bool { + s, ok := n.Selectors[network] + if !ok || s == "" { + return false + } + return true +} + +// GetNetworkSelection gets the network selection for a given Ceph network, or nil if the network +// doesn't have a selection. +func (n *NetworkSpec) GetNetworkSelection(clusterNamespace string, network CephNetworkType) (*nadv1.NetworkSelectionElement, error) { + if !n.NetworkHasSelection(network) { + return nil, nil // no selection for network + } + s := n.Selectors[network] + // From documentation of the "k8s.v1.cni.cncf.io/network-status" annotation, valid JSON inputs + // must be in list form, surrounded with brackets. The NAD utility library will only parse + // list-format JSON input. However, old versions of Rook code allowed non-list JSON objects. + // In order to support legacy users, make an attempt to turn single-JSON-object inputs into + // len(1) lists so that they parse correctly by the util library. Do not advertise this + // "feature" in documentation since it is not technically the correct format. + if strings.HasPrefix(s, "{") && strings.HasSuffix(s, "}") { + s = "[" + s + "]" + } + selection, err := nadutils.ParseNetworkAnnotation(s, clusterNamespace) + if err != nil { + return nil, errors.Wrapf(err, "failed to parse %q network selector %q", network, s) + } + if len(selection) != 1 { + return nil, errors.Errorf("%q network selector %q has multiple (%d) selections, which is not supported", network, s, len(selection)) + } + return selection[0], nil +} + +// NetworkSelectionsToAnnotationValue converts NetworkAttachmentDefinition network selection +// elements to an annotation value for the "k8s.v1.cni.cncf.io/networks" annotation key. +func NetworkSelectionsToAnnotationValue(selections ...*nadv1.NetworkSelectionElement) (string, error) { + reduced := []*nadv1.NetworkSelectionElement{} + for _, s := range selections { + if s != nil { + reduced = append(reduced, s) + } + } + if len(reduced) == 0 { + return "", nil + } + b, err := json.Marshal(reduced) + if err != nil { + return "", errors.Wrap(err, "failed to convert network selections to annotation value") + } + return string(b), nil +} + +func (n *AddressRangesSpec) IsEmpty() bool { + return n == nil || len(n.Public) == 0 && len(n.Cluster) == 0 +} + +func (n *AddressRangesSpec) Validate() error { + if n.IsEmpty() { + return nil + } + + allRanges := append(n.Public, n.Cluster...) + invalid := []string{} + for _, cidr := range allRanges { + _, _, err := net.ParseCIDR(string(cidr)) + if err != nil { + // returned err is "invalid CIDR: " & not more useful than invalid list below + invalid = append(invalid, string(cidr)) + } + } + if len(invalid) == 0 { + return nil + } + + return fmt.Errorf("%d network ranges are invalid: %v", len(invalid), invalid) +} + +// String turns a CIDR list into a comma-delimited string of CIDRs +func (l *CIDRList) String() string { + sl := []string{} + for _, c := range *l { + sl = append(sl, string(c)) + } + return strings.Join(sl, ", ") +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/nfs.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/nfs.go new file mode 100644 index 00000000000..37d5a3cf700 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/nfs.go @@ -0,0 +1,105 @@ +/* +Copyright 2022 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "reflect" + + "github.com/pkg/errors" + v1 "k8s.io/api/core/v1" +) + +// KerberosEnabled returns true if Kerberos is enabled from the spec. +func (n *NFSSecuritySpec) KerberosEnabled() bool { + if n == nil { + return false + } + if n.Kerberos != nil { + return true + } + return false +} + +// GetPrincipalName gets the principal name for the Kerberos spec or the default value if it is unset. +func (k *KerberosSpec) GetPrincipalName() string { + if k.PrincipalName == "" { + return "nfs" + } + return k.PrincipalName +} + +func (n *CephNFS) IsHostNetwork(c *ClusterSpec) bool { + if n.Spec.Server.HostNetwork != nil { + return *n.Spec.Server.HostNetwork + } + return c.Network.IsHost() +} + +func (sec *NFSSecuritySpec) Validate() error { + if sec == nil { + return nil + } + + if sec.SSSD != nil { + sidecar := sec.SSSD.Sidecar + if sidecar == nil { + return errors.New("System Security Services Daemon (SSSD) is enabled, but no runtime option is specified; supported: [runInSidecar]") + } + + if sidecar.Image == "" { + return errors.New("System Security Services Daemon (SSSD) sidecar is enabled, but no image is specified") + } + + if volSourceExistsAndIsEmpty(sidecar.SSSDConfigFile.VolumeSource.ToKubernetesVolumeSource()) { + return errors.New("System Security Services Daemon (SSSD) sidecar is enabled with config from a VolumeSource, but no source is specified") + } + + subDirs := map[string]bool{} + for _, additionalFile := range sidecar.AdditionalFiles { + subDir := additionalFile.SubPath + if subDir == "" { + return errors.New("System Security Services Daemon (SSSD) sidecar is enabled with additional file having no subPath specified") + } + + if volSourceExistsAndIsEmpty(additionalFile.VolumeSource.ToKubernetesVolumeSource()) { + return errors.Errorf("System Security Services Daemon (SSSD) sidecar is enabled with additional file (subPath %q), but no source is specified", subDir) + } + + if _, ok := subDirs[subDir]; ok { + return errors.Errorf("System Security Services Daemon (SSSD) sidecar is enabled with additional file containing duplicate subPath %q", subDir) + } + subDirs[subDir] = true + } + } + + krb := sec.Kerberos + if krb != nil { + if volSourceExistsAndIsEmpty(krb.ConfigFiles.VolumeSource.ToKubernetesVolumeSource()) { + return errors.New("Kerberos is enabled with config from a VolumeSource, but no source is specified") + } + + if volSourceExistsAndIsEmpty(krb.KeytabFile.VolumeSource.ToKubernetesVolumeSource()) { + return errors.New("Kerberos is enabled with keytab from a VolumeSource, but no source is specified") + } + } + + return nil +} + +func volSourceExistsAndIsEmpty(v *v1.VolumeSource) bool { + return v != nil && reflect.DeepEqual(*v, v1.VolumeSource{}) +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/object.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/object.go new file mode 100644 index 00000000000..8c245cdbf6e --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/object.go @@ -0,0 +1,116 @@ +/* +Copyright 2018 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +    http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "github.com/pkg/errors" +) + +const ServiceServingCertKey = "service.beta.openshift.io/serving-cert-secret-name" + +// 38 is the max length of a ceph store name as total length of the resource name cannot be more than 63 characters limit +// and there is a configmap which is formed by appending `rook-ceph-rgw--mime-types` +// so over all it brings up to (63-14-11 = 38) characters for the store name +const objectStoreNameMaxLen = 38 + +func (s *ObjectStoreSpec) IsMultisite() bool { + return s.Zone.Name != "" +} + +func (s *ObjectStoreSpec) IsTLSEnabled() bool { + return s.Gateway.SecurePort != 0 && (s.Gateway.SSLCertificateRef != "" || s.GetServiceServingCert() != "") +} + +func (s *ObjectStoreSpec) IsRGWDashboardEnabled() bool { + return s.Gateway.DashboardEnabled == nil || *s.Gateway.DashboardEnabled +} + +func (s *ObjectStoreSpec) GetPort() (int32, error) { + if s.IsTLSEnabled() { + return s.Gateway.SecurePort, nil + } else if s.Gateway.Port != 0 { + return s.Gateway.Port, nil + } + return -1, errors.New("At least one of Port or SecurePort should be non-zero") +} + +func (s *ObjectStoreSpec) IsExternal() bool { + return len(s.Gateway.ExternalRgwEndpoints) != 0 +} + +func (s *ObjectStoreSpec) IsHostNetwork(c *ClusterSpec) bool { + if s.Gateway.HostNetwork != nil { + return *s.Gateway.HostNetwork + } + return c.Network.IsHost() +} + +func (s *ObjectRealmSpec) IsPullRealm() bool { + return s.Pull.Endpoint != "" +} + +// ValidateObjectSpec validate the object store arguments +func ValidateObjectSpec(gs *CephObjectStore) error { + if gs.Name == "" { + return errors.New("missing name") + } + if gs.Namespace == "" { + return errors.New("missing namespace") + } + + // validate the object store name only if it is not an external cluster + // as external cluster won't create the rgw daemon and it's other resources + // and there is some legacy external cluster which has more length of objectstore + // so to run them successfully we are not validating the objectstore name + if !gs.Spec.IsExternal() { + if len(gs.Name) > objectStoreNameMaxLen { + return errors.New("object store name cannot be longer than 38 characters") + } + } + securePort := gs.Spec.Gateway.SecurePort + if securePort < 0 || securePort > 65535 { + return errors.Errorf("securePort value of %d must be between 0 and 65535", securePort) + } + if gs.Spec.Gateway.Port <= 0 && gs.Spec.Gateway.SecurePort <= 0 { + return errors.New("invalid create: either of port or securePort fields should be not be zero") + } + return nil +} + +func (s *ObjectStoreSpec) GetServiceServingCert() string { + if s.Gateway.Service != nil { + return s.Gateway.Service.Annotations[ServiceServingCertKey] + } + return "" +} + +func (c *CephObjectStore) GetStatusConditions() *[]Condition { + return &c.Status.Conditions +} + +func (z *CephObjectZone) GetStatusConditions() *[]Condition { + return &z.Status.Conditions +} + +// String returns an addressable string representation of the EndpointAddress. +func (e *EndpointAddress) String() string { + // hostname is easier to read, and it is probably less likely to change, so prefer it over IP + if e.Hostname != "" { + return e.Hostname + } + return e.IP +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/placement.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/placement.go new file mode 100644 index 00000000000..5bbd74d9e5a --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/placement.go @@ -0,0 +1,147 @@ +/* +Copyright 2018 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package v1 + +import ( + v1 "k8s.io/api/core/v1" +) + +func (p PlacementSpec) All() Placement { + return p[KeyAll] +} + +// ApplyToPodSpec adds placement to a pod spec +func (p Placement) ApplyToPodSpec(t *v1.PodSpec) { + if t.Affinity == nil { + t.Affinity = &v1.Affinity{} + } + if p.NodeAffinity != nil { + t.Affinity.NodeAffinity = p.mergeNodeAffinity(t.Affinity.NodeAffinity) + } + if p.PodAffinity != nil { + t.Affinity.PodAffinity = p.PodAffinity.DeepCopy() + } + if p.PodAntiAffinity != nil { + t.Affinity.PodAntiAffinity = p.PodAntiAffinity.DeepCopy() + } + if p.Tolerations != nil { + t.Tolerations = p.mergeTolerations(t.Tolerations) + } + if p.TopologySpreadConstraints != nil { + t.TopologySpreadConstraints = p.TopologySpreadConstraints + } +} + +func (p Placement) mergeNodeAffinity(nodeAffinity *v1.NodeAffinity) *v1.NodeAffinity { + // no node affinity is specified yet, so return the placement's nodeAffinity + result := p.NodeAffinity.DeepCopy() + if nodeAffinity == nil { + return result + } + + // merge the preferred node affinity that was already specified, and the placement's nodeAffinity + result.PreferredDuringSchedulingIgnoredDuringExecution = append( + nodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution, + p.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution...) + + // nothing to merge if no affinity was passed in + if nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution == nil { + return result + } + // take the desired affinity if there was none on the placement + if p.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution == nil { + result.RequiredDuringSchedulingIgnoredDuringExecution = nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution + return result + } + // take the desired affinity node selectors without the need to merge + if len(nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms) == 0 { + return result + } + // take the placement affinity node selectors without the need to merge + if len(p.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms) == 0 { + // take the placement from the first option since the second isn't specified + result.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms = + nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms + return result + } + + // merge the match expressions together since they are defined in both placements + // this will only work if we want an "and" between all the expressions, more complex conditions won't work with this merge + var nodeTerm v1.NodeSelectorTerm + nodeTerm.MatchExpressions = append( + nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions, + p.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions...) + nodeTerm.MatchFields = append( + nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchFields, + p.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchFields...) + result.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0] = nodeTerm + + return result +} + +func (p Placement) mergeTolerations(tolerations []v1.Toleration) []v1.Toleration { + // no toleration is specified yet, return placement's toleration + if tolerations == nil { + return p.Tolerations + } + + return append(p.Tolerations, tolerations...) +} + +// Merge returns a Placement which results from merging the attributes of the +// original Placement with the attributes of the supplied one. The supplied +// Placement's attributes will override the original ones if defined. +func (p Placement) Merge(with Placement) Placement { + ret := p + if with.NodeAffinity != nil { + ret.NodeAffinity = with.NodeAffinity + } + if with.PodAffinity != nil { + ret.PodAffinity = with.PodAffinity + } + if with.PodAntiAffinity != nil { + ret.PodAntiAffinity = with.PodAntiAffinity + } + if with.Tolerations != nil { + ret.Tolerations = ret.mergeTolerations(with.Tolerations) + } + if with.TopologySpreadConstraints != nil { + ret.TopologySpreadConstraints = with.TopologySpreadConstraints + } + return ret +} + +// GetMgrPlacement returns the placement for the MGR service +func GetMgrPlacement(p PlacementSpec) Placement { + return p.All().Merge(p[KeyMgr]) +} + +// GetMonPlacement returns the placement for the MON service +func GetMonPlacement(p PlacementSpec) Placement { + return p.All().Merge(p[KeyMon]) +} + +// GetArbiterPlacement returns the placement for the arbiter MON service +func GetArbiterPlacement(p PlacementSpec) Placement { + // If the mon is the arbiter in a stretch cluster and its placement is specified, return it + // without merging with the "all" placement so it can be handled separately from all other daemons + return p[KeyMonArbiter] +} + +// GetOSDPlacement returns the placement for the OSD service +func GetOSDPlacement(p PlacementSpec) Placement { + return p.All().Merge(p[KeyOSD]) +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/pool.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/pool.go new file mode 100644 index 00000000000..ed8855e23cd --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/pool.go @@ -0,0 +1,101 @@ +/* +Copyright 2020 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "github.com/pkg/errors" +) + +func (p *PoolSpec) IsReplicated() bool { + return p.Replicated.Size > 0 +} + +func (p *PoolSpec) IsErasureCoded() bool { + return p.ErasureCoded.CodingChunks > 0 || p.ErasureCoded.DataChunks > 0 +} + +func (p *PoolSpec) IsHybridStoragePool() bool { + return p.Replicated.HybridStorage != nil +} + +func (p *PoolSpec) IsCompressionEnabled() bool { + return p.CompressionMode != "" +} + +func (p *ReplicatedSpec) IsTargetRatioEnabled() bool { + return p.TargetSizeRatio != 0 +} + +// ValidateCephBlockPool validates specifically a CephBlockPool's spec (not just any NamedPoolSpec) +func ValidateCephBlockPool(p *CephBlockPool) error { + if p.Spec.Name == "device_health_metrics" || p.Spec.Name == ".mgr" || p.Spec.Name == ".nfs" { + if p.Spec.IsErasureCoded() { + return errors.Errorf("invalid CephBlockPool spec: ceph built-in pool %q cannot be erasure coded", p.Name) + } + } + + return validatePoolSpec(p.ToNamedPoolSpec()) +} + +// validate any NamedPoolSpec +func validatePoolSpec(ps NamedPoolSpec) error { + // Checks if either ErasureCoded or Replicated fields are set + if ps.ErasureCoded.CodingChunks <= 0 && ps.ErasureCoded.DataChunks <= 0 && ps.Replicated.TargetSizeRatio <= 0 && ps.Replicated.Size <= 0 { + return errors.New("invalid pool spec: either of erasurecoded or replicated fields should be set") + } + // Check if any of the ErasureCoded fields are populated. Then check if replicated is populated. Both can't be populated at same time. + if ps.ErasureCoded.CodingChunks > 0 || ps.ErasureCoded.DataChunks > 0 || ps.ErasureCoded.Algorithm != "" { + if ps.Replicated.Size > 0 || ps.Replicated.TargetSizeRatio > 0 { + return errors.New("invalid pool spec: both erasurecoded and replicated fields cannot be set at the same time") + } + } + + if ps.Replicated.Size == 0 && ps.Replicated.TargetSizeRatio == 0 { + // Check if datachunks is set and has value less than 2. + if ps.ErasureCoded.DataChunks < 2 && ps.ErasureCoded.DataChunks != 0 { + return errors.New("invalid pool spec: erasurecoded.datachunks needs minimum value of 2") + } + + // Check if codingchunks is set and has value less than 1. + if ps.ErasureCoded.CodingChunks < 1 && ps.ErasureCoded.CodingChunks != 0 { + return errors.New("invalid pool spec: erasurecoded.codingchunks needs minimum value of 1") + } + } + return nil +} + +func (p *CephBlockPool) ToNamedPoolSpec() NamedPoolSpec { + // If the name is not overridden in the pool spec.name, set it to the name of the pool CR + name := p.Spec.Name + if name == "" { + // Set the name of the pool CR since a name override wasn't specified in the spec + name = p.Name + } + return NamedPoolSpec{ + Name: name, + PoolSpec: p.Spec.PoolSpec, + } +} + +func (p *CephBlockPool) GetStatusConditions() *[]Condition { + return &p.Status.Conditions +} + +// SnapshotSchedulesEnabled returns whether snapshot schedules are desired +func (p *MirroringSpec) SnapshotSchedulesEnabled() bool { + return len(p.SnapshotSchedules) > 0 +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/priorityclasses.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/priorityclasses.go new file mode 100644 index 00000000000..05e56c61625 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/priorityclasses.go @@ -0,0 +1,73 @@ +/* +Copyright 2019 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +// All returns the priority class name defined for 'all' daemons in the Ceph cluster CRD. +func (p PriorityClassNamesSpec) All() string { + if val, ok := p[KeyAll]; ok { + return val + } + return "" +} + +// GetMgrPriorityClassName returns the priority class name for the MGR service +func GetMgrPriorityClassName(p PriorityClassNamesSpec) string { + if _, ok := p[KeyMgr]; !ok { + return p.All() + } + return p[KeyMgr] +} + +// GetMonPriorityClassName returns the priority class name for the monitors +func GetMonPriorityClassName(p PriorityClassNamesSpec) string { + if _, ok := p[KeyMon]; !ok { + return p.All() + } + return p[KeyMon] +} + +// GetOSDPriorityClassName returns the priority class name for the OSDs +func GetOSDPriorityClassName(p PriorityClassNamesSpec) string { + if _, ok := p[KeyOSD]; !ok { + return p.All() + } + return p[KeyOSD] +} + +// GetCleanupPriorityClassName returns the priority class name for the cleanup job +func GetCleanupPriorityClassName(p PriorityClassNamesSpec) string { + if _, ok := p[KeyCleanup]; !ok { + return p.All() + } + return p[KeyCleanup] +} + +// GetCrashCollectorPriorityClassName returns the priority class name for the crashcollector +func GetCrashCollectorPriorityClassName(p PriorityClassNamesSpec) string { + if _, ok := p[KeyCrashCollector]; !ok { + return p.All() + } + return p[KeyCrashCollector] +} + +// GetCephExporterPriorityClassName returns the priority class name for the ceph-exporter +func GetCephExporterPriorityClassName(p PriorityClassNamesSpec) string { + if _, ok := p[KeyCephExporter]; !ok { + return p.All() + } + return p[KeyCephExporter] +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/register.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/register.go new file mode 100644 index 00000000000..1eebf794954 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/register.go @@ -0,0 +1,102 @@ +/* +Copyright 2020 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +    http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + bktv1alpha1 "github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1" + cephrookio "github.com/rook/rook/pkg/apis/ceph.rook.io" +) + +const ( + CustomResourceGroup = "ceph.rook.io" + Version = "v1" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: cephrookio.CustomResourceGroupName, Version: Version} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // SchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. + SchemeBuilder runtime.SchemeBuilder + localSchemeBuilder = &SchemeBuilder + AddToScheme = localSchemeBuilder.AddToScheme +) + +func init() { + // We only register manually written functions here. The registration of the + // generated functions takes place in the generated files. The separation + // makes the code compile even when the generated files are missing. + localSchemeBuilder.Register(addKnownTypes) +} + +// Adds the list of known types to api.Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &CephClient{}, + &CephClientList{}, + &CephCluster{}, + &CephClusterList{}, + &CephBlockPool{}, + &CephBlockPoolList{}, + &CephFilesystem{}, + &CephFilesystemList{}, + &CephNFS{}, + &CephNFSList{}, + &CephObjectStore{}, + &CephObjectStoreList{}, + &CephObjectStoreUser{}, + &CephObjectStoreUserList{}, + &CephObjectRealm{}, + &CephObjectRealmList{}, + &CephObjectZoneGroup{}, + &CephObjectZoneGroupList{}, + &CephObjectZone{}, + &CephObjectZoneList{}, + &CephBucketTopic{}, + &CephBucketTopicList{}, + &CephBucketNotification{}, + &CephBucketNotificationList{}, + &CephRBDMirror{}, + &CephRBDMirrorList{}, + &CephFilesystemMirror{}, + &CephFilesystemMirrorList{}, + &CephFilesystemSubVolumeGroup{}, + &CephFilesystemSubVolumeGroupList{}, + &CephBlockPoolRadosNamespace{}, + &CephBlockPoolRadosNamespaceList{}, + &CephCOSIDriver{}, + &CephCOSIDriverList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + scheme.AddKnownTypes(bktv1alpha1.SchemeGroupVersion, + &bktv1alpha1.ObjectBucketClaim{}, + &bktv1alpha1.ObjectBucketClaimList{}, + &bktv1alpha1.ObjectBucket{}, + &bktv1alpha1.ObjectBucketList{}, + ) + metav1.AddToGroupVersion(scheme, bktv1alpha1.SchemeGroupVersion) + return nil +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/resources.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/resources.go new file mode 100644 index 00000000000..1f621333eaf --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/resources.go @@ -0,0 +1,106 @@ +/* +Copyright 2018 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + v1 "k8s.io/api/core/v1" +) + +const ( + // ResourcesKeyMon represents the name of resource in the CR for a mon + ResourcesKeyMon = "mon" + // ResourcesKeyMgr represents the name of resource in the CR for a mgr + ResourcesKeyMgr = "mgr" + // ResourcesKeyMgrSidecar represents the name of resource in the CR for a mgr + ResourcesKeyMgrSidecar = "mgr-sidecar" + // ResourcesKeyOSD represents the name of a resource in the CR for all OSDs + ResourcesKeyOSD = "osd" + // ResourcesKeyPrepareOSD represents the name of resource in the CR for the osd prepare job + ResourcesKeyPrepareOSD = "prepareosd" + // ResourcesKeyMDS represents the name of resource in the CR for the mds + ResourcesKeyMDS = "mds" + // ResourcesKeyCrashCollector represents the name of resource in the CR for the crash + ResourcesKeyCrashCollector = "crashcollector" + // ResourcesKeyLogCollector represents the name of resource in the CR for the log + ResourcesKeyLogCollector = "logcollector" + // ResourcesKeyRBDMirror represents the name of resource in the CR for the rbd mirror + ResourcesKeyRBDMirror = "rbdmirror" + // ResourcesKeyFilesystemMirror represents the name of resource in the CR for the filesystem mirror + ResourcesKeyFilesystemMirror = "fsmirror" + // ResourcesKeyCleanup represents the name of resource in the CR for the cleanup + ResourcesKeyCleanup = "cleanup" + // ResourcesKeyCleanup represents the name of resource in the CR for ceph-exporter + ResourcesKeyCephExporter = "exporter" +) + +// GetMgrResources returns the placement for the MGR service +func GetMgrResources(p ResourceSpec) v1.ResourceRequirements { + return p[ResourcesKeyMgr] +} + +// GetMgrSidecarResources returns the placement for the MGR sidecar container +func GetMgrSidecarResources(p ResourceSpec) v1.ResourceRequirements { + return p[ResourcesKeyMgrSidecar] +} + +// GetMonResources returns the placement for the monitors +func GetMonResources(p ResourceSpec) v1.ResourceRequirements { + return p[ResourcesKeyMon] +} + +// GetOSDResources returns the placement for all OSDs or for OSDs of specified device class (hdd, nvme, ssd) +func GetOSDResources(p ResourceSpec, deviceClass string) v1.ResourceRequirements { + if deviceClass == "" { + return p[ResourcesKeyOSD] + } + // if device class specified, but not set in requirements return common osd requirements if present + r, ok := p[getOSDResourceKeyForDeviceClass(deviceClass)] + if ok { + return r + } + return p[ResourcesKeyOSD] +} + +// getOSDResourceKeyForDeviceClass returns key name for device class in resources spec +func getOSDResourceKeyForDeviceClass(deviceClass string) string { + return ResourcesKeyOSD + "-" + deviceClass +} + +// GetPrepareOSDResources returns the placement for the OSDs prepare job +func GetPrepareOSDResources(p ResourceSpec) v1.ResourceRequirements { + return p[ResourcesKeyPrepareOSD] +} + +// GetCrashCollectorResources returns the placement for the crash daemon +func GetCrashCollectorResources(p ResourceSpec) v1.ResourceRequirements { + return p[ResourcesKeyCrashCollector] +} + +// GetLogCollectorResources returns the placement for the crash daemon +func GetLogCollectorResources(p ResourceSpec) v1.ResourceRequirements { + return p[ResourcesKeyLogCollector] +} + +// GetCleanupResources returns the placement for the cleanup job +func GetCleanupResources(p ResourceSpec) v1.ResourceRequirements { + return p[ResourcesKeyCleanup] +} + +// GetCleanupResources returns the placement for the cleanup job +func GetCephExporterResources(p ResourceSpec) v1.ResourceRequirements { + return p[ResourcesKeyCephExporter] +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/scc.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/scc.go new file mode 100644 index 00000000000..8db6efb7454 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/scc.go @@ -0,0 +1,81 @@ +/* +Copyright 2021 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +    http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "fmt" + + secv1 "github.com/openshift/api/security/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// NewSecurityContextConstraints returns a new SecurityContextConstraints for Rook-Ceph to run on +// OpenShift. +func NewSecurityContextConstraints(name string, namespaces ...string) *secv1.SecurityContextConstraints { + return &secv1.SecurityContextConstraints{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "security.openshift.io/v1", + Kind: "SecurityContextConstraints", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + AllowPrivilegedContainer: true, + AllowHostDirVolumePlugin: true, + ReadOnlyRootFilesystem: false, + AllowHostIPC: true, + AllowHostNetwork: false, + AllowHostPorts: false, + AllowedCapabilities: []corev1.Capability{"MKNOD"}, + RequiredDropCapabilities: []corev1.Capability{"ALL"}, + DefaultAddCapabilities: []corev1.Capability{}, + RunAsUser: secv1.RunAsUserStrategyOptions{ + Type: secv1.RunAsUserStrategyRunAsAny, + }, + SELinuxContext: secv1.SELinuxContextStrategyOptions{ + Type: secv1.SELinuxStrategyMustRunAs, + }, + FSGroup: secv1.FSGroupStrategyOptions{ + Type: secv1.FSGroupStrategyMustRunAs, + }, + SupplementalGroups: secv1.SupplementalGroupsStrategyOptions{ + Type: secv1.SupplementalGroupsStrategyRunAsAny, + }, + Volumes: []secv1.FSType{ + secv1.FSTypeConfigMap, + secv1.FSTypeDownwardAPI, + secv1.FSTypeEmptyDir, + secv1.FSTypeHostPath, + secv1.FSTypePersistentVolumeClaim, + secv1.FSProjected, + secv1.FSTypeSecret, + }, + Users: func() (users []string) { + for _, ns := range namespaces { + users = append(users, []string{ + fmt.Sprintf("system:serviceaccount:%s:rook-ceph-system", ns), + fmt.Sprintf("system:serviceaccount:%s:default", ns), + fmt.Sprintf("system:serviceaccount:%s:rook-ceph-mgr", ns), + fmt.Sprintf("system:serviceaccount:%s:rook-ceph-osd", ns), + fmt.Sprintf("system:serviceaccount:%s:rook-ceph-rgw", ns), + }...) + } + return + }(), + } +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/security.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/security.go new file mode 100644 index 00000000000..45d0186c90a --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/security.go @@ -0,0 +1,78 @@ +/* +Copyright 2020 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +    http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "strings" + + "github.com/hashicorp/vault/api" + "github.com/libopenstorage/secrets" + "github.com/libopenstorage/secrets/vault" +) + +var ( + VaultTLSConnectionDetails = []string{api.EnvVaultCACert, api.EnvVaultClientCert, api.EnvVaultClientKey} +) + +// IsEnabled return whether a KMS is configured +func (kms *KeyManagementServiceSpec) IsEnabled() bool { + return len(kms.ConnectionDetails) != 0 +} + +// IsTokenAuthEnabled return whether KMS token auth is enabled +func (kms *KeyManagementServiceSpec) IsTokenAuthEnabled() bool { + return kms.TokenSecretName != "" +} + +// IsK8sAuthEnabled return whether KMS Kubernetes auth is enabled +func (kms *KeyManagementServiceSpec) IsK8sAuthEnabled() bool { + return getParam(kms.ConnectionDetails, vault.AuthMethod) == vault.AuthMethodKubernetes && kms.TokenSecretName == "" +} + +// IsVaultKMS return whether Vault KMS is configured +func (kms *KeyManagementServiceSpec) IsVaultKMS() bool { + return getParam(kms.ConnectionDetails, "KMS_PROVIDER") == secrets.TypeVault +} + +// IsIBMKeyProtectKMS return whether IBM Key Protect KMS is configured +func (kms *KeyManagementServiceSpec) IsIBMKeyProtectKMS() bool { + return getParam(kms.ConnectionDetails, "KMS_PROVIDER") == "ibmkeyprotect" +} + +// IsKMIPKMS return whether KMIP KMS is configured +func (kms *KeyManagementServiceSpec) IsKMIPKMS() bool { + return getParam(kms.ConnectionDetails, "KMS_PROVIDER") == "kmip" +} + +// IsTLSEnabled return KMS TLS details are configured +func (kms *KeyManagementServiceSpec) IsTLSEnabled() bool { + for _, tlsOption := range VaultTLSConnectionDetails { + tlsSecretName := getParam(kms.ConnectionDetails, tlsOption) + if tlsSecretName != "" { + return true + } + } + return false +} + +// getParam returns the value of the KMS config option +func getParam(kmsConfig map[string]string, param string) string { + if val, ok := kmsConfig[param]; ok && val != "" { + return strings.TrimSpace(val) + } + return "" +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/status.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/status.go new file mode 100644 index 00000000000..ce91612f253 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/status.go @@ -0,0 +1,74 @@ +/* +Copyright 2021 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// SetStatusCondition sets the corresponding condition in conditions to newCondition. +// conditions must be non-nil. +// 1. if the condition of the specified type already exists (all fields of the existing condition are updated to +// newCondition, LastTransitionTime is set to now if the new status differs from the old status) +// 2. if a condition of the specified type does not exist (LastTransitionTime is set to now() if unset, and newCondition is appended) +func SetStatusCondition(conditions *[]Condition, newCondition Condition) { + if conditions == nil { + return + } + + now := metav1.NewTime(time.Now()) + + existingCondition := FindStatusCondition(*conditions, newCondition.Type) + if existingCondition == nil { + if newCondition.LastTransitionTime.IsZero() { + newCondition.LastTransitionTime = now + newCondition.LastHeartbeatTime = now + } + *conditions = append(*conditions, newCondition) + return + } + + if existingCondition.Status != newCondition.Status { + existingCondition.Status = newCondition.Status + if !newCondition.LastTransitionTime.IsZero() { + existingCondition.LastTransitionTime = newCondition.LastTransitionTime + } else { + existingCondition.LastTransitionTime = now + } + } + + existingCondition.Reason = newCondition.Reason + existingCondition.Message = newCondition.Message + if !newCondition.LastHeartbeatTime.IsZero() { + existingCondition.LastHeartbeatTime = newCondition.LastHeartbeatTime + } else { + existingCondition.LastHeartbeatTime = now + } +} + +// FindStatusCondition finds the conditionType in conditions. +func FindStatusCondition(conditions []Condition, conditionType ConditionType) *Condition { + for i := range conditions { + if conditions[i].Type == conditionType { + return &conditions[i] + } + } + + return nil +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/storage.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/storage.go new file mode 100644 index 00000000000..36a66ebdb39 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/storage.go @@ -0,0 +1,198 @@ +/* +Copyright 2018 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package v1 + +import "fmt" + +type StoreType string + +const ( + // StoreTypeBlueStore is the bluestore backend storage for OSDs + StoreTypeBlueStore StoreType = "bluestore" + + // StoreTypeBlueStoreRDR is the bluestore-rdr backed storage for OSDs + StoreTypeBlueStoreRDR StoreType = "bluestore-rdr" +) + +// AnyUseAllDevices gets whether to use all devices +func (s *StorageScopeSpec) AnyUseAllDevices() bool { + if s.Selection.GetUseAllDevices() { + return true + } + + for _, n := range s.Nodes { + if n.Selection.GetUseAllDevices() { + return true + } + } + + return false +} + +// ClearUseAllDevices clears all devices +func (s *StorageScopeSpec) ClearUseAllDevices() { + clear := false + s.Selection.UseAllDevices = &clear + for i := range s.Nodes { + s.Nodes[i].Selection.UseAllDevices = &clear + } +} + +// NodeExists returns true if the node exists in the storage spec. False otherwise. +func (s *StorageScopeSpec) NodeExists(nodeName string) bool { + for i := range s.Nodes { + if s.Nodes[i].Name == nodeName { + return true + } + } + return false +} + +// Fully resolves the config of the given node name, taking into account cluster level and node level specified config. +// In general, the more fine grained the configuration is specified, the more precedence it takes. Fully resolved +// configuration for the node has the following order of precedence. +// 1) Node (config defined on the node itself) +// 2) Cluster (config defined on the cluster) +// 3) Default values (if no config exists for the node or cluster) +func (s *StorageScopeSpec) ResolveNode(nodeName string) *Node { + // find the requested storage node first, if it exists + var node *Node + for i := range s.Nodes { + if s.Nodes[i].Name == nodeName { + node = &(s.Nodes[i]) + break + } + } + + if node == nil { + // a node with the given name was not found + return nil + } + if node.Config == nil { + node.Config = map[string]string{} + } + + // now resolve all properties that haven't already been set on the node + s.resolveNodeSelection(node) + s.resolveNodeConfig(node) + + return node +} + +func (s *StorageScopeSpec) resolveNodeSelection(node *Node) { + if node.Selection.UseAllDevices == nil { + if s.Selection.UseAllDevices != nil { + // the node does not have a value specified for use all devices, but the cluster does. Use the cluster's. + node.Selection.UseAllDevices = s.Selection.UseAllDevices + } else { + // neither node nor cluster have a value set for use all devices, use the default value. + node.Selection.UseAllDevices = newBool(false) + } + } + + resolveString(&(node.Selection.DeviceFilter), s.Selection.DeviceFilter, "") + resolveString(&(node.Selection.DevicePathFilter), s.Selection.DevicePathFilter, "") + + if len(node.Selection.Devices) == 0 { + node.Selection.Devices = s.Devices + } + + if len(node.Selection.VolumeClaimTemplates) == 0 { + node.Selection.VolumeClaimTemplates = s.VolumeClaimTemplates + } +} + +func (s *StorageScopeSpec) resolveNodeConfig(node *Node) { + // check for any keys the parent scope has that the node does not + for scopeKey, scopeVal := range s.Config { + if _, ok := node.Config[scopeKey]; !ok { + // the node's config does not have an entry that the parent scope does, add the parent's + // value for that key to the node's config. + node.Config[scopeKey] = scopeVal + } + } +} + +// NodeWithNameExists returns true if the storage spec defines a node with the given name. +func (s *StorageScopeSpec) NodeWithNameExists(name string) bool { + for _, n := range s.Nodes { + if name == n.Name { + return true + } + } + return false +} + +// GetUseAllDevices return if all devices should be used. +func (s *Selection) GetUseAllDevices() bool { + return s.UseAllDevices != nil && *(s.UseAllDevices) +} + +func resolveString(setting *string, parent, defaultVal string) { + if *setting == "" { + if parent != "" { + *setting = parent + } else { + *setting = defaultVal + } + } +} + +func newBool(val bool) *bool { + return &val +} + +// NodesByName implements an interface to sort nodes by name +type NodesByName []Node + +func (s NodesByName) Len() int { + return len(s) +} + +func (s NodesByName) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s NodesByName) Less(i, j int) bool { + return s[i].Name < s[j].Name +} + +// IsOnPVCEncrypted returns whether a Ceph Cluster on PVC will be encrypted +func (s *StorageScopeSpec) IsOnPVCEncrypted() bool { + for _, storageClassDeviceSet := range s.StorageClassDeviceSets { + if storageClassDeviceSet.Encrypted { + return true + } + } + + return false +} + +// GetOSDStore returns osd backend store type provided in the cluster spec +func (s *StorageScopeSpec) GetOSDStore() string { + if s.Store.Type == "" { + return string(StoreTypeBlueStore) + } + return s.Store.Type +} + +// GetOSDStoreFlag returns osd backend store type prefixed with "--" +func (s *StorageScopeSpec) GetOSDStoreFlag() string { + if s.Store.Type == "" { + return fmt.Sprintf("--%s", StoreTypeBlueStore) + } + return fmt.Sprintf("--%s", s.Store.Type) +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/topic.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/topic.go new file mode 100644 index 00000000000..40d9d8f9855 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/topic.go @@ -0,0 +1,84 @@ +/* +Copyright 2021 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +    http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "net/url" + "strings" + + "github.com/pkg/errors" +) + +func validateURI(uri string, expectedSchemas []string) error { + parsedURI, err := url.Parse(uri) + if err != nil { + return err + } + schema := strings.ToLower(parsedURI.Scheme) + for _, s := range expectedSchemas { + if s == schema { + return nil + } + } + return errors.Errorf("URI schema %q no in %v", schema, expectedSchemas) +} + +func ValidateHTTPSpec(s *HTTPEndpointSpec) error { + return validateURI(s.URI, []string{"http", "https"}) +} + +func ValidateAMQPSpec(s *AMQPEndpointSpec) error { + return validateURI(s.URI, []string{"amqp", "amqps"}) +} + +func ValidateKafkaSpec(s *KafkaEndpointSpec) error { + return validateURI(s.URI, []string{"kafka"}) +} + +// ValidateTopicSpec validate the bucket notification topic arguments +func (t *CephBucketTopic) ValidateTopicSpec() error { + hasEndpoint := false + if t.Spec.Endpoint.HTTP != nil { + hasEndpoint = true + if err := ValidateHTTPSpec(t.Spec.Endpoint.HTTP); err != nil { + return err + } + } + if t.Spec.Endpoint.AMQP != nil { + if hasEndpoint { + return errors.New("multiple endpoint specs") + } + hasEndpoint = true + if err := ValidateAMQPSpec(t.Spec.Endpoint.AMQP); err != nil { + return err + } + } + if t.Spec.Endpoint.Kafka != nil { + if hasEndpoint { + return errors.New("multiple endpoint specs") + } + hasEndpoint = true + if err := ValidateKafkaSpec(t.Spec.Endpoint.Kafka); err != nil { + return err + } + } + + if !hasEndpoint { + return errors.New("missing endpoint spec") + } + return nil +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/types.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/types.go new file mode 100644 index 00000000000..ca5eaa79735 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/types.go @@ -0,0 +1,3075 @@ +/* +Copyright 2020 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "time" + + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// *************************************************************************** +// IMPORTANT FOR CODE GENERATION +// If the types in this file are updated, you will need to run +// `make codegen` to generate the new types under the client/clientset folder. +// *************************************************************************** + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephCluster is a Ceph storage cluster +// +kubebuilder:printcolumn:name="DataDirHostPath",type=string,JSONPath=`.spec.dataDirHostPath`,description="Directory used on the K8s nodes" +// +kubebuilder:printcolumn:name="MonCount",type=string,JSONPath=`.spec.mon.count`,description="Number of MONs" +// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` +// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase` +// +kubebuilder:printcolumn:name="Message",type=string,JSONPath=`.status.message`,description="Message" +// +kubebuilder:printcolumn:name="Health",type=string,JSONPath=`.status.ceph.health`,description="Ceph Health" +// +kubebuilder:printcolumn:name="External",type=boolean,JSONPath=`.spec.external.enable` +// +kubebuilder:printcolumn:name="FSID",type=string,JSONPath=`.status.ceph.fsid`,description="Ceph FSID" +// +kubebuilder:subresource:status +type CephCluster struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + Spec ClusterSpec `json:"spec"` + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + // +nullable + Status ClusterStatus `json:"status,omitempty"` +} + +// CephClusterHealthCheckSpec represent the healthcheck for Ceph daemons +type CephClusterHealthCheckSpec struct { + // DaemonHealth is the health check for a given daemon + // +optional + // +nullable + DaemonHealth DaemonHealthSpec `json:"daemonHealth,omitempty"` + // LivenessProbe allows changing the livenessProbe configuration for a given daemon + // +optional + LivenessProbe map[KeyType]*ProbeSpec `json:"livenessProbe,omitempty"` + // StartupProbe allows changing the startupProbe configuration for a given daemon + // +optional + StartupProbe map[KeyType]*ProbeSpec `json:"startupProbe,omitempty"` +} + +// DaemonHealthSpec is a daemon health check +type DaemonHealthSpec struct { + // Status represents the health check settings for the Ceph health + // +optional + // +nullable + Status HealthCheckSpec `json:"status,omitempty"` + // Monitor represents the health check settings for the Ceph monitor + // +optional + // +nullable + Monitor HealthCheckSpec `json:"mon,omitempty"` + // ObjectStorageDaemon represents the health check settings for the Ceph OSDs + // +optional + // +nullable + ObjectStorageDaemon HealthCheckSpec `json:"osd,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephClusterList is a list of CephCluster +type CephClusterList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephCluster `json:"items"` +} + +// ClusterSpec represents the specification of Ceph Cluster +type ClusterSpec struct { + // The version information that instructs Rook to orchestrate a particular version of Ceph. + // +optional + // +nullable + CephVersion CephVersionSpec `json:"cephVersion,omitempty"` + + // A spec for available storage in the cluster and how it should be used + // +optional + // +nullable + Storage StorageScopeSpec `json:"storage,omitempty"` + + // The annotations-related configuration to add/set on each Pod related object. + // +nullable + // +optional + Annotations AnnotationsSpec `json:"annotations,omitempty"` + + // The labels-related configuration to add/set on each Pod related object. + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Labels LabelsSpec `json:"labels,omitempty"` + + // The placement-related configuration to pass to kubernetes (affinity, node selector, tolerations). + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Placement PlacementSpec `json:"placement,omitempty"` + + // Network related configuration + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Network NetworkSpec `json:"network,omitempty"` + + // Resources set resource requests and limits + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Resources ResourceSpec `json:"resources,omitempty"` + + // PriorityClassNames sets priority classes on components + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + PriorityClassNames PriorityClassNamesSpec `json:"priorityClassNames,omitempty"` + + // The path on the host where config and data can be persisted + // +kubebuilder:validation:Pattern=`^/(\S+)` + // +kubebuilder:validation:XValidation:message="DataDirHostPath is immutable",rule="self == oldSelf" + // +optional + DataDirHostPath string `json:"dataDirHostPath,omitempty"` + + // SkipUpgradeChecks defines if an upgrade should be forced even if one of the check fails + // +optional + SkipUpgradeChecks bool `json:"skipUpgradeChecks,omitempty"` + + // ContinueUpgradeAfterChecksEvenIfNotHealthy defines if an upgrade should continue even if PGs are not clean + // +optional + ContinueUpgradeAfterChecksEvenIfNotHealthy bool `json:"continueUpgradeAfterChecksEvenIfNotHealthy,omitempty"` + + // WaitTimeoutForHealthyOSDInMinutes defines the time the operator would wait before an OSD can be stopped for upgrade or restart. + // If the timeout exceeds and OSD is not ok to stop, then the operator would skip upgrade for the current OSD and proceed with the next one + // if `continueUpgradeAfterChecksEvenIfNotHealthy` is `false`. If `continueUpgradeAfterChecksEvenIfNotHealthy` is `true`, then operator would + // continue with the upgrade of an OSD even if its not ok to stop after the timeout. This timeout won't be applied if `skipUpgradeChecks` is `true`. + // The default wait timeout is 10 minutes. + // +optional + WaitTimeoutForHealthyOSDInMinutes time.Duration `json:"waitTimeoutForHealthyOSDInMinutes,omitempty"` + + // A spec for configuring disruption management. + // +nullable + // +optional + DisruptionManagement DisruptionManagementSpec `json:"disruptionManagement,omitempty"` + + // A spec for mon related options + // +optional + // +nullable + Mon MonSpec `json:"mon,omitempty"` + + // A spec for the crash controller + // +optional + // +nullable + CrashCollector CrashCollectorSpec `json:"crashCollector,omitempty"` + + // Dashboard settings + // +optional + // +nullable + Dashboard DashboardSpec `json:"dashboard,omitempty"` + + // Prometheus based Monitoring settings + // +optional + // +nullable + Monitoring MonitoringSpec `json:"monitoring,omitempty"` + + // Whether the Ceph Cluster is running external to this Kubernetes cluster + // mon, mgr, osd, mds, and discover daemons will not be created for external clusters. + // +optional + // +nullable + External ExternalSpec `json:"external,omitempty"` + + // A spec for mgr related options + // +optional + // +nullable + Mgr MgrSpec `json:"mgr,omitempty"` + + // Remove the OSD that is out and safe to remove only if this option is true + // +optional + RemoveOSDsIfOutAndSafeToRemove bool `json:"removeOSDsIfOutAndSafeToRemove,omitempty"` + + // Indicates user intent when deleting a cluster; blocks orchestration and should not be set if cluster + // deletion is not imminent. + // +optional + // +nullable + CleanupPolicy CleanupPolicySpec `json:"cleanupPolicy,omitempty"` + + // Internal daemon healthchecks and liveness probe + // +optional + // +nullable + HealthCheck CephClusterHealthCheckSpec `json:"healthCheck,omitempty"` + + // Security represents security settings + // +optional + // +nullable + Security SecuritySpec `json:"security,omitempty"` + + // Logging represents loggings settings + // +optional + // +nullable + LogCollector LogCollectorSpec `json:"logCollector,omitempty"` + + // CSI Driver Options applied per cluster. + // +optional + CSI CSIDriverSpec `json:"csi,omitempty"` + + // Ceph Config options + // +optional + // +nullable + CephConfig map[string]map[string]string `json:"cephConfig,omitempty"` +} + +// CSIDriverSpec defines CSI Driver settings applied per cluster. +type CSIDriverSpec struct { + // ReadAffinity defines the read affinity settings for CSI driver. + // +optional + ReadAffinity ReadAffinitySpec `json:"readAffinity"` + // CephFS defines CSI Driver settings for CephFS driver. + // +optional + CephFS CSICephFSSpec `json:"cephfs,omitempty"` +} + +// CSICephFSSpec defines the settings for CephFS CSI driver. +type CSICephFSSpec struct { + // KernelMountOptions defines the mount options for kernel mounter. + // +optional + KernelMountOptions string `json:"kernelMountOptions,omitempty"` + // FuseMountOptions defines the mount options for ceph fuse mounter. + // +optional + FuseMountOptions string `json:"fuseMountOptions,omitempty"` +} + +// ReadAffinitySpec defines the read affinity settings for CSI driver. +type ReadAffinitySpec struct { + // Enables read affinity for CSI driver. + // +optional + Enabled bool `json:"enabled"` + // CrushLocationLabels defines which node labels to use + // as CRUSH location. This should correspond to the values set in + // the CRUSH map. + // +optional + CrushLocationLabels []string `json:"crushLocationLabels,omitempty"` +} + +// LogCollectorSpec is the logging spec +type LogCollectorSpec struct { + // Enabled represents whether the log collector is enabled + // +optional + Enabled bool `json:"enabled,omitempty"` + // Periodicity is the periodicity of the log rotation. + // +kubebuilder:validation:Pattern=`^$|^(hourly|daily|weekly|monthly|1h|24h|1d)$` + // +optional + Periodicity string `json:"periodicity,omitempty"` + // MaxLogSize is the maximum size of the log per ceph daemons. Must be at least 1M. + // +optional + MaxLogSize *resource.Quantity `json:"maxLogSize,omitempty"` +} + +// SecuritySpec is security spec to include various security items such as kms +type SecuritySpec struct { + // KeyManagementService is the main Key Management option + // +optional + // +nullable + KeyManagementService KeyManagementServiceSpec `json:"kms,omitempty"` + // KeyRotation defines options for Key Rotation. + // +optional + // +nullable + KeyRotation KeyRotationSpec `json:"keyRotation,omitempty"` +} + +// ObjectStoreSecuritySpec is spec to define security features like encryption +type ObjectStoreSecuritySpec struct { + // +optional + // +nullable + SecuritySpec `json:""` + + // The settings for supporting AWS-SSE:S3 with RGW + // +optional + // +nullable + ServerSideEncryptionS3 KeyManagementServiceSpec `json:"s3,omitempty"` +} + +// KeyManagementServiceSpec represent various details of the KMS server +type KeyManagementServiceSpec struct { + // ConnectionDetails contains the KMS connection details (address, port etc) + // +optional + // +nullable + // +kubebuilder:pruning:PreserveUnknownFields + ConnectionDetails map[string]string `json:"connectionDetails,omitempty"` + // TokenSecretName is the kubernetes secret containing the KMS token + // +optional + TokenSecretName string `json:"tokenSecretName,omitempty"` +} + +// KeyRotationSpec represents the settings for Key Rotation. +type KeyRotationSpec struct { + // Enabled represents whether the key rotation is enabled. + // +optional + // +kubebuilder:default=false + Enabled bool `json:"enabled,omitempty"` + // Schedule represents the cron schedule for key rotation. + // +optional + Schedule string `json:"schedule,omitempty"` +} + +// CephVersionSpec represents the settings for the Ceph version that Rook is orchestrating. +type CephVersionSpec struct { + // Image is the container image used to launch the ceph daemons, such as quay.io/ceph/ceph: + // The full list of images can be found at https://quay.io/repository/ceph/ceph?tab=tags + // +optional + Image string `json:"image,omitempty"` + + // Whether to allow unsupported versions (do not set to true in production) + // +optional + AllowUnsupported bool `json:"allowUnsupported,omitempty"` + + // ImagePullPolicy describes a policy for if/when to pull a container image + // One of Always, Never, IfNotPresent. + // +kubebuilder:validation:Enum=IfNotPresent;Always;Never;"" + // +optional + ImagePullPolicy v1.PullPolicy `json:"imagePullPolicy,omitempty"` +} + +// DashboardSpec represents the settings for the Ceph dashboard +type DashboardSpec struct { + // Enabled determines whether to enable the dashboard + // +optional + Enabled bool `json:"enabled,omitempty"` + // URLPrefix is a prefix for all URLs to use the dashboard with a reverse proxy + // +optional + URLPrefix string `json:"urlPrefix,omitempty"` + // Port is the dashboard webserver port + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=65535 + // +optional + Port int `json:"port,omitempty"` + // SSL determines whether SSL should be used + // +optional + SSL bool `json:"ssl,omitempty"` + // Endpoint for the Prometheus host + // +optional + PrometheusEndpoint string `json:"prometheusEndpoint,omitempty"` + // Whether to verify the ssl endpoint for prometheus. Set to false for a self-signed cert. + // +optional + PrometheusEndpointSSLVerify bool `json:"prometheusEndpointSSLVerify,omitempty"` +} + +// MonitoringSpec represents the settings for Prometheus based Ceph monitoring +type MonitoringSpec struct { + // Enabled determines whether to create the prometheus rules for the ceph cluster. If true, the prometheus + // types must exist or the creation will fail. Default is false. + // +optional + Enabled bool `json:"enabled,omitempty"` + + // Whether to disable the metrics reported by Ceph. If false, the prometheus mgr module and Ceph exporter are enabled. + // If true, the prometheus mgr module and Ceph exporter are both disabled. Default is false. + // +optional + MetricsDisabled bool `json:"metricsDisabled,omitempty"` + + // ExternalMgrEndpoints points to an existing Ceph prometheus exporter endpoint + // +optional + // +nullable + ExternalMgrEndpoints []v1.EndpointAddress `json:"externalMgrEndpoints,omitempty"` + + // ExternalMgrPrometheusPort Prometheus exporter port + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=65535 + // +optional + ExternalMgrPrometheusPort uint16 `json:"externalMgrPrometheusPort,omitempty"` + + // Port is the prometheus server port + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=65535 + // +optional + Port int `json:"port,omitempty"` + + // Interval determines prometheus scrape interval + // +optional + Interval *metav1.Duration `json:"interval,omitempty"` +} + +// ClusterStatus represents the status of a Ceph cluster +type ClusterStatus struct { + State ClusterState `json:"state,omitempty"` + Phase ConditionType `json:"phase,omitempty"` + Message string `json:"message,omitempty"` + Conditions []Condition `json:"conditions,omitempty"` + CephStatus *CephStatus `json:"ceph,omitempty"` + CephStorage *CephStorage `json:"storage,omitempty"` + CephVersion *ClusterVersion `json:"version,omitempty"` + // ObservedGeneration is the latest generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` +} + +// CephDaemonsVersions show the current ceph version for different ceph daemons +type CephDaemonsVersions struct { + // Mon shows Mon Ceph version + // +optional + Mon map[string]int `json:"mon,omitempty"` + // Mgr shows Mgr Ceph version + // +optional + Mgr map[string]int `json:"mgr,omitempty"` + // Osd shows Osd Ceph version + // +optional + Osd map[string]int `json:"osd,omitempty"` + // Rgw shows Rgw Ceph version + // +optional + Rgw map[string]int `json:"rgw,omitempty"` + // Mds shows Mds Ceph version + // +optional + Mds map[string]int `json:"mds,omitempty"` + // RbdMirror shows RbdMirror Ceph version + // +optional + RbdMirror map[string]int `json:"rbd-mirror,omitempty"` + // CephFSMirror shows CephFSMirror Ceph version + // +optional + CephFSMirror map[string]int `json:"cephfs-mirror,omitempty"` + // Overall shows overall Ceph version + // +optional + Overall map[string]int `json:"overall,omitempty"` +} + +// CephStatus is the details health of a Ceph Cluster +type CephStatus struct { + Health string `json:"health,omitempty"` + Details map[string]CephHealthMessage `json:"details,omitempty"` + LastChecked string `json:"lastChecked,omitempty"` + LastChanged string `json:"lastChanged,omitempty"` + PreviousHealth string `json:"previousHealth,omitempty"` + Capacity Capacity `json:"capacity,omitempty"` + // +optional + Versions *CephDaemonsVersions `json:"versions,omitempty"` + FSID string `json:"fsid,omitempty"` +} + +// Capacity is the capacity information of a Ceph Cluster +type Capacity struct { + TotalBytes uint64 `json:"bytesTotal,omitempty"` + UsedBytes uint64 `json:"bytesUsed,omitempty"` + AvailableBytes uint64 `json:"bytesAvailable,omitempty"` + LastUpdated string `json:"lastUpdated,omitempty"` +} + +// CephStorage represents flavors of Ceph Cluster Storage +type CephStorage struct { + DeviceClasses []DeviceClasses `json:"deviceClasses,omitempty"` + OSD OSDStatus `json:"osd,omitempty"` +} + +// DeviceClasses represents device classes of a Ceph Cluster +type DeviceClasses struct { + Name string `json:"name,omitempty"` +} + +// OSDStatus represents OSD status of the ceph Cluster +type OSDStatus struct { + // StoreType is a mapping between the OSD backend stores and number of OSDs using these stores + StoreType map[string]int `json:"storeType,omitempty"` +} + +// ClusterVersion represents the version of a Ceph Cluster +type ClusterVersion struct { + Image string `json:"image,omitempty"` + Version string `json:"version,omitempty"` +} + +// CephHealthMessage represents the health message of a Ceph Cluster +type CephHealthMessage struct { + Severity string `json:"severity"` + Message string `json:"message"` +} + +// Condition represents a status condition on any Rook-Ceph Custom Resource. +type Condition struct { + Type ConditionType `json:"type,omitempty"` + Status v1.ConditionStatus `json:"status,omitempty"` + Reason ConditionReason `json:"reason,omitempty"` + Message string `json:"message,omitempty"` + LastHeartbeatTime metav1.Time `json:"lastHeartbeatTime,omitempty"` + LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` +} + +// ConditionReason is a reason for a condition +type ConditionReason string + +const ( + // ClusterCreatedReason is cluster created reason + ClusterCreatedReason ConditionReason = "ClusterCreated" + // ClusterConnectedReason is cluster connected reason + ClusterConnectedReason ConditionReason = "ClusterConnected" + // ClusterProgressingReason is cluster progressing reason + ClusterProgressingReason ConditionReason = "ClusterProgressing" + // ClusterDeletingReason is cluster deleting reason + ClusterDeletingReason ConditionReason = "ClusterDeleting" + // ClusterConnectingReason is cluster connecting reason + ClusterConnectingReason ConditionReason = "ClusterConnecting" + + // ReconcileSucceeded represents when a resource reconciliation was successful. + ReconcileSucceeded ConditionReason = "ReconcileSucceeded" + // ReconcileFailed represents when a resource reconciliation failed. + ReconcileFailed ConditionReason = "ReconcileFailed" + // ReconcileStarted represents when a resource reconciliation started. + ReconcileStarted ConditionReason = "ReconcileStarted" + + // DeletingReason represents when Rook has detected a resource object should be deleted. + DeletingReason ConditionReason = "Deleting" + // ObjectHasDependentsReason represents when a resource object has dependents that are blocking + // deletion. + ObjectHasDependentsReason ConditionReason = "ObjectHasDependents" + // ObjectHasNoDependentsReason represents when a resource object has no dependents that are + // blocking deletion. + ObjectHasNoDependentsReason ConditionReason = "ObjectHasNoDependents" +) + +// ConditionType represent a resource's status +type ConditionType string + +const ( + // ConditionConnecting represents Connecting state of an object + ConditionConnecting ConditionType = "Connecting" + // ConditionConnected represents Connected state of an object + ConditionConnected ConditionType = "Connected" + // ConditionProgressing represents Progressing state of an object + ConditionProgressing ConditionType = "Progressing" + // ConditionReady represents Ready state of an object + ConditionReady ConditionType = "Ready" + // ConditionFailure represents Failure state of an object + ConditionFailure ConditionType = "Failure" + // ConditionDeleting represents Deleting state of an object + ConditionDeleting ConditionType = "Deleting" + + // ConditionDeletionIsBlocked represents when deletion of the object is blocked. + ConditionDeletionIsBlocked ConditionType = "DeletionIsBlocked" +) + +// ClusterState represents the state of a Ceph Cluster +type ClusterState string + +const ( + // ClusterStateCreating represents the Creating state of a Ceph Cluster + ClusterStateCreating ClusterState = "Creating" + // ClusterStateCreated represents the Created state of a Ceph Cluster + ClusterStateCreated ClusterState = "Created" + // ClusterStateUpdating represents the Updating state of a Ceph Cluster + ClusterStateUpdating ClusterState = "Updating" + // ClusterStateConnecting represents the Connecting state of a Ceph Cluster + ClusterStateConnecting ClusterState = "Connecting" + // ClusterStateConnected represents the Connected state of a Ceph Cluster + ClusterStateConnected ClusterState = "Connected" + // ClusterStateError represents the Error state of a Ceph Cluster + ClusterStateError ClusterState = "Error" +) + +// MonSpec represents the specification of the monitor +// +kubebuilder:validation:XValidation:message="zones must be less than or equal to count",rule="!has(self.zones) || (has(self.zones) && (size(self.zones) <= self.count))" +// +kubebuilder:validation:XValidation:message="stretchCluster zones must be equal to 3",rule="!has(self.stretchCluster) || (has(self.stretchCluster) && (size(self.stretchCluster.zones) > 0) && (size(self.stretchCluster.zones) == 3))" +type MonSpec struct { + // Count is the number of Ceph monitors + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=9 + // +optional + Count int `json:"count,omitempty"` + // AllowMultiplePerNode determines if we can run multiple monitors on the same node (not recommended) + // +optional + AllowMultiplePerNode bool `json:"allowMultiplePerNode,omitempty"` + // +optional + FailureDomainLabel string `json:"failureDomainLabel,omitempty"` + // Zones are specified when we want to provide zonal awareness to mons + // +optional + Zones []MonZoneSpec `json:"zones,omitempty"` + // StretchCluster is the stretch cluster specification + // +optional + StretchCluster *StretchClusterSpec `json:"stretchCluster,omitempty"` + // VolumeClaimTemplate is the PVC definition + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + VolumeClaimTemplate *v1.PersistentVolumeClaim `json:"volumeClaimTemplate,omitempty"` +} + +// StretchClusterSpec represents the specification of a stretched Ceph Cluster +type StretchClusterSpec struct { + // FailureDomainLabel the failure domain name (e,g: zone) + // +optional + FailureDomainLabel string `json:"failureDomainLabel,omitempty"` + // SubFailureDomain is the failure domain within a zone + // +optional + SubFailureDomain string `json:"subFailureDomain,omitempty"` + // Zones is the list of zones + // +optional + // +nullable + Zones []MonZoneSpec `json:"zones,omitempty"` +} + +// MonZoneSpec represents the specification of a zone in a Ceph Cluster +type MonZoneSpec struct { + // Name is the name of the zone + // +optional + Name string `json:"name,omitempty"` + // Arbiter determines if the zone contains the arbiter used for stretch cluster mode + // +optional + Arbiter bool `json:"arbiter,omitempty"` + // VolumeClaimTemplate is the PVC template + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + VolumeClaimTemplate *v1.PersistentVolumeClaim `json:"volumeClaimTemplate,omitempty"` +} + +// MgrSpec represents options to configure a ceph mgr +type MgrSpec struct { + // Count is the number of manager daemons to run + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=5 + // +optional + Count int `json:"count,omitempty"` + // AllowMultiplePerNode allows to run multiple managers on the same node (not recommended) + // +optional + AllowMultiplePerNode bool `json:"allowMultiplePerNode,omitempty"` + // Modules is the list of ceph manager modules to enable/disable + // +optional + // +nullable + Modules []Module `json:"modules,omitempty"` +} + +// Module represents mgr modules that the user wants to enable or disable +type Module struct { + // Name is the name of the ceph manager module + // +optional + Name string `json:"name,omitempty"` + // Enabled determines whether a module should be enabled or not + // +optional + Enabled bool `json:"enabled,omitempty"` +} + +// ExternalSpec represents the options supported by an external cluster +// +kubebuilder:pruning:PreserveUnknownFields +// +nullable +type ExternalSpec struct { + // Enable determines whether external mode is enabled or not + // +optional + Enable bool `json:"enable,omitempty"` +} + +// CrashCollectorSpec represents options to configure the crash controller +type CrashCollectorSpec struct { + // Disable determines whether we should enable the crash collector + // +optional + Disable bool `json:"disable,omitempty"` + + // DaysToRetain represents the number of days to retain crash until they get pruned + // +optional + DaysToRetain uint `json:"daysToRetain,omitempty"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephBlockPool represents a Ceph Storage Pool +// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase` +// +kubebuilder:subresource:status +type CephBlockPool struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + Spec NamedBlockPoolSpec `json:"spec"` + // +kubebuilder:pruning:PreserveUnknownFields + Status *CephBlockPoolStatus `json:"status,omitempty"` +} + +// CephBlockPoolList is a list of Ceph Storage Pools +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type CephBlockPoolList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephBlockPool `json:"items"` +} + +const ( + // DefaultFailureDomain for PoolSpec + DefaultFailureDomain = "host" + // DefaultCRUSHRoot is the default name of the CRUSH root bucket + DefaultCRUSHRoot = "default" +) + +// PoolSpec represents the spec of ceph pool +type PoolSpec struct { + // The failure domain: osd/host/(region or zone if available) - technically also any type in the crush map + // +optional + FailureDomain string `json:"failureDomain,omitempty"` + + // The root of the crush hierarchy utilized by the pool + // +optional + // +nullable + CrushRoot string `json:"crushRoot,omitempty"` + + // The device class the OSD should set to for use in the pool + // +optional + // +nullable + DeviceClass string `json:"deviceClass,omitempty"` + + // DEPRECATED: use Parameters instead, e.g., Parameters["compression_mode"] = "force" + // The inline compression mode in Bluestore OSD to set to (options are: none, passive, aggressive, force) + // +kubebuilder:validation:Enum=none;passive;aggressive;force;"" + // Do NOT set a default value for kubebuilder as this will override the Parameters + // +optional + // +nullable + CompressionMode string `json:"compressionMode,omitempty"` + + // The replication settings + // +optional + Replicated ReplicatedSpec `json:"replicated,omitempty"` + + // The erasure code settings + // +optional + ErasureCoded ErasureCodedSpec `json:"erasureCoded,omitempty"` + + // Parameters is a list of properties to enable on a given pool + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + // +nullable + Parameters map[string]string `json:"parameters,omitempty"` + + // EnableRBDStats is used to enable gathering of statistics for all RBD images in the pool + EnableRBDStats bool `json:"enableRBDStats,omitempty"` + + // The mirroring settings + Mirroring MirroringSpec `json:"mirroring,omitempty"` + + // The mirroring statusCheck + // +kubebuilder:pruning:PreserveUnknownFields + StatusCheck MirrorHealthCheckSpec `json:"statusCheck,omitempty"` + + // The quota settings + // +optional + // +nullable + Quotas QuotaSpec `json:"quotas,omitempty"` +} + +// NamedBlockPoolSpec allows a block pool to be created with a non-default name. +// This is more specific than the NamedPoolSpec so we get schema validation on the +// allowed pool names that can be specified. +type NamedBlockPoolSpec struct { + // The desired name of the pool if different from the CephBlockPool CR name. + // +kubebuilder:validation:Enum=device_health_metrics;.nfs;.mgr + // +optional + Name string `json:"name,omitempty"` + // The core pool configuration + PoolSpec `json:",inline"` +} + +// NamedPoolSpec represents the named ceph pool spec +type NamedPoolSpec struct { + // Name of the pool + Name string `json:"name,omitempty"` + // PoolSpec represents the spec of ceph pool + PoolSpec `json:",inline"` +} + +// MirrorHealthCheckSpec represents the health specification of a Ceph Storage Pool mirror +type MirrorHealthCheckSpec struct { + // +optional + // +nullable + Mirror HealthCheckSpec `json:"mirror,omitempty"` +} + +// CephBlockPoolStatus represents the mirroring status of Ceph Storage Pool +type CephBlockPoolStatus struct { + // +optional + Phase ConditionType `json:"phase,omitempty"` + // +optional + MirroringStatus *MirroringStatusSpec `json:"mirroringStatus,omitempty"` + // +optional + MirroringInfo *MirroringInfoSpec `json:"mirroringInfo,omitempty"` + // +optional + SnapshotScheduleStatus *SnapshotScheduleStatusSpec `json:"snapshotScheduleStatus,omitempty"` + // +optional + // +nullable + Info map[string]string `json:"info,omitempty"` + // ObservedGeneration is the latest generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + Conditions []Condition `json:"conditions,omitempty"` +} + +// MirroringStatusSpec is the status of the pool mirroring +type MirroringStatusSpec struct { + // PoolMirroringStatus is the mirroring status of a pool + // +optional + PoolMirroringStatus `json:",inline"` + // LastChecked is the last time time the status was checked + // +optional + LastChecked string `json:"lastChecked,omitempty"` + // LastChanged is the last time time the status last changed + // +optional + LastChanged string `json:"lastChanged,omitempty"` + // Details contains potential status errors + // +optional + Details string `json:"details,omitempty"` +} + +// PoolMirroringStatus is the pool mirror status +type PoolMirroringStatus struct { + // Summary is the mirroring status summary + // +optional + Summary *PoolMirroringStatusSummarySpec `json:"summary,omitempty"` +} + +// PoolMirroringStatusSummarySpec is the summary output of the command +type PoolMirroringStatusSummarySpec struct { + // Health is the mirroring health + // +optional + Health string `json:"health,omitempty"` + // DaemonHealth is the health of the mirroring daemon + // +optional + DaemonHealth string `json:"daemon_health,omitempty"` + // ImageHealth is the health of the mirrored image + // +optional + ImageHealth string `json:"image_health,omitempty"` + // States is the various state for all mirrored images + // +optional + // +nullable + States StatesSpec `json:"states,omitempty"` +} + +// StatesSpec are rbd images mirroring state +type StatesSpec struct { + // StartingReplay is when the replay of the mirroring journal starts + // +optional + StartingReplay int `json:"starting_replay,omitempty"` + // Replaying is when the replay of the mirroring journal is on-going + // +optional + Replaying int `json:"replaying,omitempty"` + // Syncing is when the image is syncing + // +optional + Syncing int `json:"syncing,omitempty"` + // StopReplaying is when the replay of the mirroring journal stops + // +optional + StopReplaying int `json:"stopping_replay,omitempty"` + // Stopped is when the mirroring state is stopped + // +optional + Stopped int `json:"stopped,omitempty"` + // Unknown is when the mirroring state is unknown + // +optional + Unknown int `json:"unknown,omitempty"` + // Error is when the mirroring state is errored + // +optional + Error int `json:"error,omitempty"` +} + +// MirroringInfoSpec is the status of the pool mirroring +type MirroringInfoSpec struct { + // +optional + *PoolMirroringInfo `json:",inline"` + // +optional + LastChecked string `json:"lastChecked,omitempty"` + // +optional + LastChanged string `json:"lastChanged,omitempty"` + // +optional + Details string `json:"details,omitempty"` +} + +// PoolMirroringInfo is the mirroring info of a given pool +type PoolMirroringInfo struct { + // Mode is the mirroring mode + // +optional + Mode string `json:"mode,omitempty"` + // SiteName is the current site name + // +optional + SiteName string `json:"site_name,omitempty"` + // Peers are the list of peer sites connected to that cluster + // +optional + Peers []PeersSpec `json:"peers,omitempty"` +} + +// PeersSpec contains peer details +type PeersSpec struct { + // UUID is the peer UUID + // +optional + UUID string `json:"uuid,omitempty"` + // Direction is the peer mirroring direction + // +optional + Direction string `json:"direction,omitempty"` + // SiteName is the current site name + // +optional + SiteName string `json:"site_name,omitempty"` + // MirrorUUID is the mirror UUID + // +optional + MirrorUUID string `json:"mirror_uuid,omitempty"` + // ClientName is the CephX user used to connect to the peer + // +optional + ClientName string `json:"client_name,omitempty"` +} + +// SnapshotScheduleStatusSpec is the status of the snapshot schedule +type SnapshotScheduleStatusSpec struct { + // SnapshotSchedules is the list of snapshots scheduled + // +nullable + // +optional + SnapshotSchedules []SnapshotSchedulesSpec `json:"snapshotSchedules,omitempty"` + // LastChecked is the last time time the status was checked + // +optional + LastChecked string `json:"lastChecked,omitempty"` + // LastChanged is the last time time the status last changed + // +optional + LastChanged string `json:"lastChanged,omitempty"` + // Details contains potential status errors + // +optional + Details string `json:"details,omitempty"` +} + +// SnapshotSchedulesSpec is the list of snapshot scheduled for images in a pool +type SnapshotSchedulesSpec struct { + // Pool is the pool name + // +optional + Pool string `json:"pool,omitempty"` + // Namespace is the RADOS namespace the image is part of + // +optional + Namespace string `json:"namespace,omitempty"` + // Image is the mirrored image + // +optional + Image string `json:"image,omitempty"` + // Items is the list schedules times for a given snapshot + // +optional + Items []SnapshotSchedule `json:"items,omitempty"` +} + +// SnapshotSchedule is a schedule +type SnapshotSchedule struct { + // Interval is the interval in which snapshots will be taken + // +optional + Interval string `json:"interval,omitempty"` + // StartTime is the snapshot starting time + // +optional + StartTime string `json:"start_time,omitempty"` +} + +// Status represents the status of an object +type Status struct { + // +optional + Phase string `json:"phase,omitempty"` + // ObservedGeneration is the latest generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + Conditions []Condition `json:"conditions,omitempty"` +} + +// ReplicatedSpec represents the spec for replication in a pool +type ReplicatedSpec struct { + // Size - Number of copies per object in a replicated storage pool, including the object itself (required for replicated pool type) + // +kubebuilder:validation:Minimum=0 + Size uint `json:"size"` + + // TargetSizeRatio gives a hint (%) to Ceph in terms of expected consumption of the total cluster capacity + // +optional + TargetSizeRatio float64 `json:"targetSizeRatio,omitempty"` + + // RequireSafeReplicaSize if false allows you to set replica 1 + // +optional + RequireSafeReplicaSize bool `json:"requireSafeReplicaSize,omitempty"` + + // ReplicasPerFailureDomain the number of replica in the specified failure domain + // +kubebuilder:validation:Minimum=1 + // +optional + ReplicasPerFailureDomain uint `json:"replicasPerFailureDomain,omitempty"` + + // SubFailureDomain the name of the sub-failure domain + // +optional + SubFailureDomain string `json:"subFailureDomain,omitempty"` + + // HybridStorage represents hybrid storage tier settings + // +optional + // +nullable + HybridStorage *HybridStorageSpec `json:"hybridStorage,omitempty"` +} + +// HybridStorageSpec represents the settings for hybrid storage pool +type HybridStorageSpec struct { + // PrimaryDeviceClass represents high performance tier (for example SSD or NVME) for Primary OSD + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:Required + // +required + PrimaryDeviceClass string `json:"primaryDeviceClass"` + // SecondaryDeviceClass represents low performance tier (for example HDDs) for remaining OSDs + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:Required + // +required + SecondaryDeviceClass string `json:"secondaryDeviceClass"` +} + +// MirroringSpec represents the setting for a mirrored pool +type MirroringSpec struct { + // Enabled whether this pool is mirrored or not + // +optional + Enabled bool `json:"enabled,omitempty"` + + // Mode is the mirroring mode: either pool or image + // +optional + Mode string `json:"mode,omitempty"` + + // SnapshotSchedules is the scheduling of snapshot for mirrored images/pools + // +optional + SnapshotSchedules []SnapshotScheduleSpec `json:"snapshotSchedules,omitempty"` + + // Peers represents the peers spec + // +nullable + // +optional + Peers *MirroringPeerSpec `json:"peers,omitempty"` +} + +// SnapshotScheduleSpec represents the snapshot scheduling settings of a mirrored pool +type SnapshotScheduleSpec struct { + // Path is the path to snapshot, only valid for CephFS + // +optional + Path string `json:"path,omitempty"` + + // Interval represent the periodicity of the snapshot. + // +optional + Interval string `json:"interval,omitempty"` + + // StartTime indicates when to start the snapshot + // +optional + StartTime string `json:"startTime,omitempty"` +} + +// QuotaSpec represents the spec for quotas in a pool +type QuotaSpec struct { + // MaxBytes represents the quota in bytes + // Deprecated in favor of MaxSize + // +optional + MaxBytes *uint64 `json:"maxBytes,omitempty"` + + // MaxSize represents the quota in bytes as a string + // +kubebuilder:validation:Pattern=`^[0-9]+[\.]?[0-9]*([KMGTPE]i|[kMGTPE])?$` + // +optional + MaxSize *string `json:"maxSize,omitempty"` + + // MaxObjects represents the quota in objects + // +optional + MaxObjects *uint64 `json:"maxObjects,omitempty"` +} + +// ErasureCodedSpec represents the spec for erasure code in a pool +type ErasureCodedSpec struct { + // Number of coding chunks per object in an erasure coded storage pool (required for erasure-coded pool type). + // This is the number of OSDs that can be lost simultaneously before data cannot be recovered. + // +kubebuilder:validation:Minimum=0 + CodingChunks uint `json:"codingChunks"` + + // Number of data chunks per object in an erasure coded storage pool (required for erasure-coded pool type). + // The number of chunks required to recover an object when any single OSD is lost is the same + // as dataChunks so be aware that the larger the number of data chunks, the higher the cost of recovery. + // +kubebuilder:validation:Minimum=0 + DataChunks uint `json:"dataChunks"` + + // The algorithm for erasure coding + // +optional + Algorithm string `json:"algorithm,omitempty"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephFilesystem represents a Ceph Filesystem +// +kubebuilder:printcolumn:name="ActiveMDS",type=string,JSONPath=`.spec.metadataServer.activeCount`,description="Number of desired active MDS daemons" +// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` +// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase` +// +kubebuilder:subresource:status +type CephFilesystem struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + Spec FilesystemSpec `json:"spec"` + // +kubebuilder:pruning:PreserveUnknownFields + Status *CephFilesystemStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephFilesystemList represents a list of Ceph Filesystems +type CephFilesystemList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephFilesystem `json:"items"` +} + +// FilesystemSpec represents the spec of a file system +type FilesystemSpec struct { + // The metadata pool settings + // +nullable + MetadataPool PoolSpec `json:"metadataPool"` + + // The data pool settings, with optional predefined pool name. + // +nullable + DataPools []NamedPoolSpec `json:"dataPools"` + + // Preserve pools on filesystem deletion + // +optional + PreservePoolsOnDelete bool `json:"preservePoolsOnDelete,omitempty"` + + // Preserve the fs in the cluster on CephFilesystem CR deletion. Setting this to true automatically implies PreservePoolsOnDelete is true. + // +optional + PreserveFilesystemOnDelete bool `json:"preserveFilesystemOnDelete,omitempty"` + + // The mds pod info + MetadataServer MetadataServerSpec `json:"metadataServer"` + + // The mirroring settings + // +nullable + // +optional + Mirroring *FSMirroringSpec `json:"mirroring,omitempty"` + + // The mirroring statusCheck + // +kubebuilder:pruning:PreserveUnknownFields + StatusCheck MirrorHealthCheckSpec `json:"statusCheck,omitempty"` +} + +// MetadataServerSpec represents the specification of a Ceph Metadata Server +type MetadataServerSpec struct { + // The number of metadata servers that are active. The remaining servers in the cluster will be in standby mode. + // +kubebuilder:validation:Minimum=1 + // +kubebuilder:validation:Maximum=10 + ActiveCount int32 `json:"activeCount"` + + // Whether each active MDS instance will have an active standby with a warm metadata cache for faster failover. + // If false, standbys will still be available, but will not have a warm metadata cache. + // +optional + ActiveStandby bool `json:"activeStandby,omitempty"` + + // The affinity to place the mds pods (default is to place on all available node) with a daemonset + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Placement Placement `json:"placement,omitempty"` + + // The annotations-related configuration to add/set on each Pod related object. + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Annotations Annotations `json:"annotations,omitempty"` + + // The labels-related configuration to add/set on each Pod related object. + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Labels Labels `json:"labels,omitempty"` + + // The resource requirements for the rgw pods + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Resources v1.ResourceRequirements `json:"resources,omitempty"` + + // PriorityClassName sets priority classes on components + // +optional + PriorityClassName string `json:"priorityClassName,omitempty"` + + // +optional + LivenessProbe *ProbeSpec `json:"livenessProbe,omitempty"` + + // +optional + StartupProbe *ProbeSpec `json:"startupProbe,omitempty"` +} + +// FSMirroringSpec represents the setting for a mirrored filesystem +type FSMirroringSpec struct { + // Enabled whether this filesystem is mirrored or not + // +optional + Enabled bool `json:"enabled,omitempty"` + + // Peers represents the peers spec + // +nullable + // +optional + Peers *MirroringPeerSpec `json:"peers,omitempty"` + + // SnapshotSchedules is the scheduling of snapshot for mirrored filesystems + // +optional + SnapshotSchedules []SnapshotScheduleSpec `json:"snapshotSchedules,omitempty"` + + // Retention is the retention policy for a snapshot schedule + // One path has exactly one retention policy. + // A policy can however contain multiple count-time period pairs in order to specify complex retention policies + // +optional + SnapshotRetention []SnapshotScheduleRetentionSpec `json:"snapshotRetention,omitempty"` +} + +// SnapshotScheduleRetentionSpec is a retention policy +type SnapshotScheduleRetentionSpec struct { + // Path is the path to snapshot + // +optional + Path string `json:"path,omitempty"` + + // Duration represents the retention duration for a snapshot + // +optional + Duration string `json:"duration,omitempty"` +} + +// CephFilesystemStatus represents the status of a Ceph Filesystem +type CephFilesystemStatus struct { + // +optional + Phase ConditionType `json:"phase,omitempty"` + // +optional + SnapshotScheduleStatus *FilesystemSnapshotScheduleStatusSpec `json:"snapshotScheduleStatus,omitempty"` + // Use only info and put mirroringStatus in it? + // +optional + // +nullable + Info map[string]string `json:"info,omitempty"` + // MirroringStatus is the filesystem mirroring status + // +optional + MirroringStatus *FilesystemMirroringInfoSpec `json:"mirroringStatus,omitempty"` + Conditions []Condition `json:"conditions,omitempty"` + // ObservedGeneration is the latest generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` +} + +// FilesystemMirroringInfo is the status of the pool mirroring +type FilesystemMirroringInfoSpec struct { + // PoolMirroringStatus is the mirroring status of a filesystem + // +nullable + // +optional + FilesystemMirroringAllInfo []FilesystemMirroringInfo `json:"daemonsStatus,omitempty"` + // LastChecked is the last time time the status was checked + // +optional + LastChecked string `json:"lastChecked,omitempty"` + // LastChanged is the last time time the status last changed + // +optional + LastChanged string `json:"lastChanged,omitempty"` + // Details contains potential status errors + // +optional + Details string `json:"details,omitempty"` +} + +// FilesystemSnapshotScheduleStatusSpec is the status of the snapshot schedule +type FilesystemSnapshotScheduleStatusSpec struct { + // SnapshotSchedules is the list of snapshots scheduled + // +nullable + // +optional + SnapshotSchedules []FilesystemSnapshotSchedulesSpec `json:"snapshotSchedules,omitempty"` + // LastChecked is the last time time the status was checked + // +optional + LastChecked string `json:"lastChecked,omitempty"` + // LastChanged is the last time time the status last changed + // +optional + LastChanged string `json:"lastChanged,omitempty"` + // Details contains potential status errors + // +optional + Details string `json:"details,omitempty"` +} + +// FilesystemSnapshotSchedulesSpec is the list of snapshot scheduled for images in a pool +type FilesystemSnapshotSchedulesSpec struct { + // Fs is the name of the Ceph Filesystem + // +optional + Fs string `json:"fs,omitempty"` + // Subvol is the name of the sub volume + // +optional + Subvol string `json:"subvol,omitempty"` + // Path is the path on the filesystem + // +optional + Path string `json:"path,omitempty"` + // +optional + RelPath string `json:"rel_path,omitempty"` + // +optional + Schedule string `json:"schedule,omitempty"` + // +optional + Retention FilesystemSnapshotScheduleStatusRetention `json:"retention,omitempty"` +} + +// FilesystemSnapshotScheduleStatusRetention is the retention specification for a filesystem snapshot schedule +type FilesystemSnapshotScheduleStatusRetention struct { + // Start is when the snapshot schedule starts + // +optional + Start string `json:"start,omitempty"` + // Created is when the snapshot schedule was created + // +optional + Created string `json:"created,omitempty"` + // First is when the first snapshot schedule was taken + // +optional + First string `json:"first,omitempty"` + // Last is when the last snapshot schedule was taken + // +optional + Last string `json:"last,omitempty"` + // LastPruned is when the last snapshot schedule was pruned + // +optional + LastPruned string `json:"last_pruned,omitempty"` + // CreatedCount is total amount of snapshots + // +optional + CreatedCount int `json:"created_count,omitempty"` + // PrunedCount is total amount of pruned snapshots + // +optional + PrunedCount int `json:"pruned_count,omitempty"` + // Active is whether the scheduled is active or not + // +optional + Active bool `json:"active,omitempty"` +} + +// FilesystemMirrorInfoSpec is the filesystem mirror status of a given filesystem +type FilesystemMirroringInfo struct { + // DaemonID is the cephfs-mirror name + // +optional + DaemonID int `json:"daemon_id,omitempty"` + // Filesystems is the list of filesystems managed by a given cephfs-mirror daemon + // +optional + Filesystems []FilesystemsSpec `json:"filesystems,omitempty"` +} + +// FilesystemsSpec is spec for the mirrored filesystem +type FilesystemsSpec struct { + // FilesystemID is the filesystem identifier + // +optional + FilesystemID int `json:"filesystem_id,omitempty"` + // Name is name of the filesystem + // +optional + Name string `json:"name,omitempty"` + // DirectoryCount is the number of directories in the filesystem + // +optional + DirectoryCount int `json:"directory_count,omitempty"` + // Peers represents the mirroring peers + // +optional + Peers []FilesystemMirrorInfoPeerSpec `json:"peers,omitempty"` +} + +// FilesystemMirrorInfoPeerSpec is the specification of a filesystem peer mirror +type FilesystemMirrorInfoPeerSpec struct { + // UUID is the peer unique identifier + // +optional + UUID string `json:"uuid,omitempty"` + // Remote are the remote cluster information + // +optional + Remote *PeerRemoteSpec `json:"remote,omitempty"` + // Stats are the stat a peer mirror + // +optional + Stats *PeerStatSpec `json:"stats,omitempty"` +} + +type PeerRemoteSpec struct { + // ClientName is cephx name + // +optional + ClientName string `json:"client_name,omitempty"` + // ClusterName is the name of the cluster + // +optional + ClusterName string `json:"cluster_name,omitempty"` + // FsName is the filesystem name + // +optional + FsName string `json:"fs_name,omitempty"` +} + +// PeerStatSpec are the mirror stat with a given peer +type PeerStatSpec struct { + // FailureCount is the number of mirroring failure + // +optional + FailureCount int `json:"failure_count,omitempty"` + // RecoveryCount is the number of recovery attempted after failures + // +optional + RecoveryCount int `json:"recovery_count,omitempty"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephObjectStore represents a Ceph Object Store Gateway +// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase` +// +kubebuilder:subresource:status +type CephObjectStore struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + Spec ObjectStoreSpec `json:"spec"` + // +kubebuilder:pruning:PreserveUnknownFields + Status *ObjectStoreStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephObjectStoreList represents a Ceph Object Store Gateways +type CephObjectStoreList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephObjectStore `json:"items"` +} + +// ObjectStoreSpec represent the spec of a pool +type ObjectStoreSpec struct { + // The metadata pool settings + // +optional + // +nullable + MetadataPool PoolSpec `json:"metadataPool,omitempty"` + + // The data pool settings + // +optional + // +nullable + DataPool PoolSpec `json:"dataPool,omitempty"` + + // Preserve pools on object store deletion + // +optional + PreservePoolsOnDelete bool `json:"preservePoolsOnDelete,omitempty"` + + // The rgw pod info + // +optional + // +nullable + Gateway GatewaySpec `json:"gateway"` + + // The multisite info + // +optional + // +nullable + Zone ZoneSpec `json:"zone,omitempty"` + + // The RGW health probes + // +optional + // +nullable + HealthCheck ObjectHealthCheckSpec `json:"healthCheck,omitempty"` + + // Security represents security settings + // +optional + // +nullable + Security *ObjectStoreSecuritySpec `json:"security,omitempty"` + + // The list of allowed namespaces in addition to the object store namespace + // where ceph object store users may be created. Specify "*" to allow all + // namespaces, otherwise list individual namespaces that are to be allowed. + // This is useful for applications that need object store credentials + // to be created in their own namespace, where neither OBCs nor COSI + // is being used to create buckets. The default is empty. + // +optional + AllowUsersInNamespaces []string `json:"allowUsersInNamespaces,omitempty"` +} + +// ObjectHealthCheckSpec represents the health check of an object store +type ObjectHealthCheckSpec struct { + // livenessProbe field is no longer used + // +kubebuilder:pruning:PreserveUnknownFields + + // +optional + ReadinessProbe *ProbeSpec `json:"readinessProbe,omitempty"` + // +optional + StartupProbe *ProbeSpec `json:"startupProbe,omitempty"` +} + +// HealthCheckSpec represents the health check of an object store bucket +type HealthCheckSpec struct { + // +optional + Disabled bool `json:"disabled,omitempty"` + // Interval is the internal in second or minute for the health check to run like 60s for 60 seconds + // +optional + Interval *metav1.Duration `json:"interval,omitempty"` + // +optional + Timeout string `json:"timeout,omitempty"` +} + +// GatewaySpec represents the specification of Ceph Object Store Gateway +type GatewaySpec struct { + // The port the rgw service will be listening on (http) + // +optional + Port int32 `json:"port,omitempty"` + + // The port the rgw service will be listening on (https) + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=65535 + // +nullable + // +optional + SecurePort int32 `json:"securePort,omitempty"` + + // The number of pods in the rgw replicaset. + // +nullable + // +optional + Instances int32 `json:"instances,omitempty"` + + // The name of the secret that stores the ssl certificate for secure rgw connections + // +nullable + // +optional + SSLCertificateRef string `json:"sslCertificateRef,omitempty"` + + // The name of the secret that stores custom ca-bundle with root and intermediate certificates. + // +nullable + // +optional + CaBundleRef string `json:"caBundleRef,omitempty"` + + // The affinity to place the rgw pods (default is to place on any available node) + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Placement Placement `json:"placement,omitempty"` + + // DisableMultisiteSyncTraffic, when true, prevents this object store's gateways from + // transmitting multisite replication data. Note that this value does not affect whether + // gateways receive multisite replication traffic: see ObjectZone.spec.customEndpoints for that. + // If false or unset, this object store's gateways will be able to transmit multisite + // replication data. + // +optional + DisableMultisiteSyncTraffic bool `json:"disableMultisiteSyncTraffic,omitempty"` + + // The annotations-related configuration to add/set on each Pod related object. + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Annotations Annotations `json:"annotations,omitempty"` + + // The labels-related configuration to add/set on each Pod related object. + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Labels Labels `json:"labels,omitempty"` + + // The resource requirements for the rgw pods + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Resources v1.ResourceRequirements `json:"resources,omitempty"` + + // PriorityClassName sets priority classes on the rgw pods + // +optional + PriorityClassName string `json:"priorityClassName,omitempty"` + + // ExternalRgwEndpoints points to external RGW endpoint(s). Multiple endpoints can be given, but + // for stability of ObjectBucketClaims, we highly recommend that users give only a single + // external RGW endpoint that is a load balancer that sends requests to the multiple RGWs. + // +nullable + // +optional + ExternalRgwEndpoints []EndpointAddress `json:"externalRgwEndpoints,omitempty"` + + // The configuration related to add/set on each rgw service. + // +optional + // +nullable + Service *RGWServiceSpec `json:"service,omitempty"` + + // Whether host networking is enabled for the rgw daemon. If not set, the network settings from the cluster CR will be applied. + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + HostNetwork *bool `json:"hostNetwork,omitempty"` + + // Whether rgw dashboard is enabled for the rgw daemon. If not set, the rgw dashboard will be enabled. + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + DashboardEnabled *bool `json:"dashboardEnabled,omitempty"` +} + +// EndpointAddress is a tuple that describes a single IP address or host name. This is a subset of +// Kubernetes's v1.EndpointAddress. +// +structType=atomic +type EndpointAddress struct { + // The IP of this endpoint. As a legacy behavior, this supports being given a DNS-adressable hostname as well. + // +optional + IP string `json:"ip" protobuf:"bytes,1,opt,name=ip"` + + // The DNS-addressable Hostname of this endpoint. This field will be preferred over IP if both are given. + // +optional + Hostname string `json:"hostname,omitempty" protobuf:"bytes,3,opt,name=hostname"` +} + +// ZoneSpec represents a Ceph Object Store Gateway Zone specification +type ZoneSpec struct { + // RGW Zone the Object Store is in + Name string `json:"name"` +} + +// ObjectStoreStatus represents the status of a Ceph Object Store resource +type ObjectStoreStatus struct { + // +optional + Phase ConditionType `json:"phase,omitempty"` + // +optional + Message string `json:"message,omitempty"` + // +optional + Endpoints ObjectEndpoints `json:"endpoints"` + // +optional + // +nullable + Info map[string]string `json:"info,omitempty"` + Conditions []Condition `json:"conditions,omitempty"` + // ObservedGeneration is the latest generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` +} + +type ObjectEndpoints struct { + // +optional + // +nullable + Insecure []string `json:"insecure"` + // +optional + // +nullable + Secure []string `json:"secure"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephObjectStoreUser represents a Ceph Object Store Gateway User +// +kubebuilder:resource:shortName=rcou;objectuser +// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase` +// +kubebuilder:subresource:status +type CephObjectStoreUser struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + Spec ObjectStoreUserSpec `json:"spec"` + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Status *ObjectStoreUserStatus `json:"status,omitempty"` +} + +// ObjectStoreUserStatus represents the status Ceph Object Store Gateway User +type ObjectStoreUserStatus struct { + // +optional + Phase string `json:"phase,omitempty"` + // +optional + // +nullable + Info map[string]string `json:"info,omitempty"` + // ObservedGeneration is the latest generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephObjectStoreUserList represents a list Ceph Object Store Gateway Users +type CephObjectStoreUserList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephObjectStoreUser `json:"items"` +} + +// ObjectStoreUserSpec represent the spec of an Objectstoreuser +type ObjectStoreUserSpec struct { + // The store the user will be created in + // +optional + Store string `json:"store,omitempty"` + // The display name for the ceph users + // +optional + DisplayName string `json:"displayName,omitempty"` + // +optional + // +nullable + Capabilities *ObjectUserCapSpec `json:"capabilities,omitempty"` + // +optional + // +nullable + Quotas *ObjectUserQuotaSpec `json:"quotas,omitempty"` + // The namespace where the parent CephCluster and CephObjectStore are found + // +optional + ClusterNamespace string `json:"clusterNamespace,omitempty"` +} + +// Additional admin-level capabilities for the Ceph object store user +type ObjectUserCapSpec struct { + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Admin capabilities to read/write Ceph object store users. Documented in https://docs.ceph.com/en/latest/radosgw/admin/?#add-remove-admin-capabilities + User string `json:"user,omitempty"` + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Admin capabilities to read/write Ceph object store users. Documented in https://docs.ceph.com/en/latest/radosgw/admin/?#add-remove-admin-capabilities + Users string `json:"users,omitempty"` + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Admin capabilities to read/write Ceph object store buckets. Documented in https://docs.ceph.com/en/latest/radosgw/admin/?#add-remove-admin-capabilities + Bucket string `json:"bucket,omitempty"` + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Admin capabilities to read/write Ceph object store buckets. Documented in https://docs.ceph.com/en/latest/radosgw/admin/?#add-remove-admin-capabilities + Buckets string `json:"buckets,omitempty"` + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Admin capabilities to read/write Ceph object store metadata. Documented in https://docs.ceph.com/en/latest/radosgw/admin/?#add-remove-admin-capabilities + MetaData string `json:"metadata,omitempty"` + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Admin capabilities to read/write Ceph object store usage. Documented in https://docs.ceph.com/en/latest/radosgw/admin/?#add-remove-admin-capabilities + Usage string `json:"usage,omitempty"` + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Admin capabilities to read/write Ceph object store zones. Documented in https://docs.ceph.com/en/latest/radosgw/admin/?#add-remove-admin-capabilities + Zone string `json:"zone,omitempty"` + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Admin capabilities to read/write roles for user. Documented in https://docs.ceph.com/en/latest/radosgw/admin/?#add-remove-admin-capabilities + Roles string `json:"roles,omitempty"` + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Admin capabilities to read/write information about the user. Documented in https://docs.ceph.com/en/latest/radosgw/admin/?#add-remove-admin-capabilities + Info string `json:"info,omitempty"` + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Add capabilities for user to send request to RGW Cache API header. Documented in https://docs.ceph.com/en/quincy/radosgw/rgw-cache/#cache-api + AMZCache string `json:"amz-cache,omitempty"` + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Add capabilities for user to change bucket index logging. Documented in https://docs.ceph.com/en/latest/radosgw/admin/?#add-remove-admin-capabilities + BiLog string `json:"bilog,omitempty"` + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Add capabilities for user to change metadata logging. Documented in https://docs.ceph.com/en/latest/radosgw/admin/?#add-remove-admin-capabilities + MdLog string `json:"mdlog,omitempty"` + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Add capabilities for user to change data logging. Documented in https://docs.ceph.com/en/latest/radosgw/admin/?#add-remove-admin-capabilities + DataLog string `json:"datalog,omitempty"` + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Add capabilities for user to change user policies. Documented in https://docs.ceph.com/en/latest/radosgw/admin/?#add-remove-admin-capabilities + UserPolicy string `json:"user-policy,omitempty"` + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Add capabilities for user to change oidc provider. Documented in https://docs.ceph.com/en/latest/radosgw/admin/?#add-remove-admin-capabilities + OidcProvider string `json:"oidc-provider,omitempty"` + // +optional + // +kubebuilder:validation:Enum={"*","read","write","read, write"} + // Add capabilities for user to set rate limiter for user and bucket. Documented in https://docs.ceph.com/en/latest/radosgw/admin/?#add-remove-admin-capabilities + RateLimit string `json:"ratelimit,omitempty"` +} + +// ObjectUserQuotaSpec can be used to set quotas for the object store user to limit their usage. See the [Ceph docs](https://docs.ceph.com/en/latest/radosgw/admin/?#quota-management) for more +type ObjectUserQuotaSpec struct { + // Maximum bucket limit for the ceph user + // +optional + // +nullable + MaxBuckets *int `json:"maxBuckets,omitempty"` + // Maximum size limit of all objects across all the user's buckets + // See https://pkg.go.dev/k8s.io/apimachinery/pkg/api/resource#Quantity for more info. + // +optional + // +nullable + MaxSize *resource.Quantity `json:"maxSize,omitempty"` + // Maximum number of objects across all the user's buckets + // +optional + // +nullable + MaxObjects *int64 `json:"maxObjects,omitempty"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephObjectRealm represents a Ceph Object Store Gateway Realm +// +kubebuilder:subresource:status +type CephObjectRealm struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + // +nullable + // +optional + Spec ObjectRealmSpec `json:"spec,omitempty"` + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Status *Status `json:"status,omitempty"` +} + +// CephObjectRealmList represents a list Ceph Object Store Gateway Realms +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type CephObjectRealmList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephObjectRealm `json:"items"` +} + +// ObjectRealmSpec represent the spec of an ObjectRealm +type ObjectRealmSpec struct { + Pull PullSpec `json:"pull,omitempty"` +} + +// PullSpec represents the pulling specification of a Ceph Object Storage Gateway Realm +type PullSpec struct { + // +kubebuilder:validation:Pattern=`^https*://` + Endpoint string `json:"endpoint,omitempty"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephObjectZoneGroup represents a Ceph Object Store Gateway Zone Group +// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase` +// +kubebuilder:subresource:status +type CephObjectZoneGroup struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + Spec ObjectZoneGroupSpec `json:"spec"` + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Status *Status `json:"status,omitempty"` +} + +// CephObjectZoneGroupList represents a list Ceph Object Store Gateway Zone Groups +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type CephObjectZoneGroupList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephObjectZoneGroup `json:"items"` +} + +// ObjectZoneGroupSpec represent the spec of an ObjectZoneGroup +type ObjectZoneGroupSpec struct { + //The display name for the ceph users + Realm string `json:"realm"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephObjectZone represents a Ceph Object Store Gateway Zone +// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase` +// +kubebuilder:subresource:status +type CephObjectZone struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + Spec ObjectZoneSpec `json:"spec"` + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Status *Status `json:"status,omitempty"` +} + +// CephObjectZoneList represents a list Ceph Object Store Gateway Zones +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type CephObjectZoneList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephObjectZone `json:"items"` +} + +// ObjectZoneSpec represent the spec of an ObjectZone +type ObjectZoneSpec struct { + //The display name for the ceph users + ZoneGroup string `json:"zoneGroup"` + + // The metadata pool settings + // +nullable + MetadataPool PoolSpec `json:"metadataPool"` + + // The data pool settings + // +nullable + DataPool PoolSpec `json:"dataPool"` + + // If this zone cannot be accessed from other peer Ceph clusters via the ClusterIP Service + // endpoint created by Rook, you must set this to the externally reachable endpoint(s). You may + // include the port in the definition. For example: "https://my-object-store.my-domain.net:443". + // In many cases, you should set this to the endpoint of the ingress resource that makes the + // CephObjectStore associated with this CephObjectStoreZone reachable to peer clusters. + // The list can have one or more endpoints pointing to different RGW servers in the zone. + // + // If a CephObjectStore endpoint is omitted from this list, that object store's gateways will + // not receive multisite replication data + // (see CephObjectStore.spec.gateway.disableMultisiteSyncTraffic). + // +nullable + // +optional + CustomEndpoints []string `json:"customEndpoints,omitempty"` + + // Preserve pools on object zone deletion + // +optional + // +kubebuilder:default=true + PreservePoolsOnDelete bool `json:"preservePoolsOnDelete"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephBucketTopic represents a Ceph Object Topic for Bucket Notifications +// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase` +// +kubebuilder:subresource:status +type CephBucketTopic struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + Spec BucketTopicSpec `json:"spec"` + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Status *BucketTopicStatus `json:"status,omitempty"` +} + +// BucketTopicStatus represents the Status of a CephBucketTopic +type BucketTopicStatus struct { + // +optional + Phase string `json:"phase,omitempty"` + // The ARN of the topic generated by the RGW + // +optional + // +nullable + ARN *string `json:"ARN,omitempty"` + // ObservedGeneration is the latest generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` +} + +// CephBucketTopicList represents a list Ceph Object Store Bucket Notification Topics +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type CephBucketTopicList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephBucketTopic `json:"items"` +} + +// BucketTopicSpec represent the spec of a Bucket Topic +type BucketTopicSpec struct { + // The name of the object store on which to define the topic + // +kubebuilder:validation:MinLength=1 + ObjectStoreName string `json:"objectStoreName"` + // The namespace of the object store on which to define the topic + // +kubebuilder:validation:MinLength=1 + ObjectStoreNamespace string `json:"objectStoreNamespace"` + // Data which is sent in each event + // +optional + OpaqueData string `json:"opaqueData,omitempty"` + // Indication whether notifications to this endpoint are persistent or not + // +optional + Persistent bool `json:"persistent,omitempty"` + // Contains the endpoint spec of the topic + Endpoint TopicEndpointSpec `json:"endpoint"` +} + +// TopicEndpointSpec contains exactly one of the endpoint specs of a Bucket Topic +type TopicEndpointSpec struct { + // Spec of HTTP endpoint + // +optional + HTTP *HTTPEndpointSpec `json:"http,omitempty"` + // Spec of AMQP endpoint + // +optional + AMQP *AMQPEndpointSpec `json:"amqp,omitempty"` + // Spec of Kafka endpoint + // +optional + Kafka *KafkaEndpointSpec `json:"kafka,omitempty"` +} + +// HTTPEndpointSpec represent the spec of an HTTP endpoint of a Bucket Topic +type HTTPEndpointSpec struct { + // The URI of the HTTP endpoint to push notification to + // +kubebuilder:validation:MinLength=1 + URI string `json:"uri"` + // Indicate whether the server certificate is validated by the client or not + // +optional + DisableVerifySSL bool `json:"disableVerifySSL,omitempty"` + // Send the notifications with the CloudEvents header: https://github.com/cloudevents/spec/blob/main/cloudevents/adapters/aws-s3.md + // Supported for Ceph Quincy (v17) or newer. + // +optional + SendCloudEvents bool `json:"sendCloudEvents,omitempty"` +} + +// AMQPEndpointSpec represent the spec of an AMQP endpoint of a Bucket Topic +type AMQPEndpointSpec struct { + // The URI of the AMQP endpoint to push notification to + // +kubebuilder:validation:MinLength=1 + URI string `json:"uri"` + // Name of the exchange that is used to route messages based on topics + // +kubebuilder:validation:MinLength=1 + Exchange string `json:"exchange"` + // Indicate whether the server certificate is validated by the client or not + // +optional + DisableVerifySSL bool `json:"disableVerifySSL,omitempty"` + // The ack level required for this topic (none/broker/routeable) + // +kubebuilder:validation:Enum=none;broker;routeable + // +kubebuilder:default=broker + // +optional + AckLevel string `json:"ackLevel,omitempty"` +} + +// KafkaEndpointSpec represent the spec of a Kafka endpoint of a Bucket Topic +type KafkaEndpointSpec struct { + // The URI of the Kafka endpoint to push notification to + // +kubebuilder:validation:MinLength=1 + URI string `json:"uri"` + // Indicate whether to use SSL when communicating with the broker + // +optional + UseSSL bool `json:"useSSL,omitempty"` + // Indicate whether the server certificate is validated by the client or not + // +optional + DisableVerifySSL bool `json:"disableVerifySSL,omitempty"` + // The ack level required for this topic (none/broker) + // +kubebuilder:validation:Enum=none;broker + // +kubebuilder:default=broker + // +optional + AckLevel string `json:"ackLevel,omitempty"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephBucketNotification represents a Bucket Notifications +// +kubebuilder:subresource:status +type CephBucketNotification struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + Spec BucketNotificationSpec `json:"spec"` + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Status *Status `json:"status,omitempty"` +} + +// CephBucketNotificationList represents a list Ceph Object Store Bucket Notification Topics +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type CephBucketNotificationList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephBucketNotification `json:"items"` +} + +// BucketNotificationSpec represent the event type of the bucket notification +// +kubebuilder:validation:Enum="s3:ObjectCreated:*";"s3:ObjectCreated:Put";"s3:ObjectCreated:Post";"s3:ObjectCreated:Copy";"s3:ObjectCreated:CompleteMultipartUpload";"s3:ObjectRemoved:*";"s3:ObjectRemoved:Delete";"s3:ObjectRemoved:DeleteMarkerCreated" +type BucketNotificationEvent string + +// BucketNotificationSpec represent the spec of a Bucket Notification +type BucketNotificationSpec struct { + // The name of the topic associated with this notification + // +kubebuilder:validation:MinLength=1 + Topic string `json:"topic"` + // List of events that should trigger the notification + // +optional + Events []BucketNotificationEvent `json:"events,omitempty"` + // Spec of notification filter + // +optional + Filter *NotificationFilterSpec `json:"filter,omitempty"` +} + +// NotificationFilterRule represent a single rule in the Notification Filter spec +type NotificationFilterRule struct { + // Name of the metadata or tag + // +kubebuilder:validation:MinLength=1 + Name string `json:"name"` + // Value to filter on + Value string `json:"value"` +} + +// NotificationKeyFilterRule represent a single key rule in the Notification Filter spec +type NotificationKeyFilterRule struct { + // Name of the filter - prefix/suffix/regex + // +kubebuilder:validation:Enum=prefix;suffix;regex + Name string `json:"name"` + // Value to filter on + Value string `json:"value"` +} + +// NotificationFilterSpec represent the spec of a Bucket Notification filter +type NotificationFilterSpec struct { + // Filters based on the object's key + // +optional + KeyFilters []NotificationKeyFilterRule `json:"keyFilters,omitempty"` + // Filters based on the object's metadata + // +optional + MetadataFilters []NotificationFilterRule `json:"metadataFilters,omitempty"` + // Filters based on the object's tags + // +optional + TagFilters []NotificationFilterRule `json:"tagFilters,omitempty"` +} + +// RGWServiceSpec represent the spec for RGW service +type RGWServiceSpec struct { + // The annotations-related configuration to add/set on each rgw service. + // nullable + // optional + Annotations Annotations `json:"annotations,omitempty"` +} + +// +genclient +// +genclient:noStatus +// +kubebuilder:resource:shortName=nfs,path=cephnfses + +// CephNFS represents a Ceph NFS +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:subresource:status +type CephNFS struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + Spec NFSGaneshaSpec `json:"spec"` + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Status *Status `json:"status,omitempty"` +} + +// CephNFSList represents a list Ceph NFSes +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type CephNFSList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephNFS `json:"items"` +} + +// NFSGaneshaSpec represents the spec of an nfs ganesha server +type NFSGaneshaSpec struct { + // RADOS is the Ganesha RADOS specification + // +nullable + // +optional + RADOS GaneshaRADOSSpec `json:"rados,omitempty"` + + // Server is the Ganesha Server specification + Server GaneshaServerSpec `json:"server"` + + // Security allows specifying security configurations for the NFS cluster + // +nullable + // +optional + Security *NFSSecuritySpec `json:"security"` +} + +// GaneshaRADOSSpec represents the specification of a Ganesha RADOS object +type GaneshaRADOSSpec struct { + // The Ceph pool used store the shared configuration for NFS-Ganesha daemons. + // This setting is deprecated, as it is internally required to be ".nfs". + // +optional + Pool string `json:"pool,omitempty"` + + // The namespace inside the Ceph pool (set by 'pool') where shared NFS-Ganesha config is stored. + // This setting is deprecated as it is internally set to the name of the CephNFS. + // +optional + Namespace string `json:"namespace,omitempty"` +} + +// GaneshaServerSpec represents the specification of a Ganesha Server +type GaneshaServerSpec struct { + // The number of active Ganesha servers + Active int `json:"active"` + + // The affinity to place the ganesha pods + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Placement Placement `json:"placement,omitempty"` + + // The annotations-related configuration to add/set on each Pod related object. + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Annotations Annotations `json:"annotations,omitempty"` + + // The labels-related configuration to add/set on each Pod related object. + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Labels Labels `json:"labels,omitempty"` + + // Resources set resource requests and limits + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Resources v1.ResourceRequirements `json:"resources,omitempty"` + + // PriorityClassName sets the priority class on the pods + // +optional + PriorityClassName string `json:"priorityClassName,omitempty"` + + // LogLevel set logging level + // +optional + LogLevel string `json:"logLevel,omitempty"` + + // Whether host networking is enabled for the Ganesha server. If not set, the network settings from the cluster CR will be applied. + // +nullable + // +optional + HostNetwork *bool `json:"hostNetwork,omitempty"` + + // A liveness-probe to verify that Ganesha server has valid run-time state. + // If LivenessProbe.Disabled is false and LivenessProbe.Probe is nil uses default probe. + // +optional + LivenessProbe *ProbeSpec `json:"livenessProbe,omitempty"` +} + +// NFSSecuritySpec represents security configurations for an NFS server pod +type NFSSecuritySpec struct { + // SSSD enables integration with System Security Services Daemon (SSSD). SSSD can be used to + // provide user ID mapping from a number of sources. See https://sssd.io for more information + // about the SSSD project. + // +optional + // +nullable + SSSD *SSSDSpec `json:"sssd,omitempty"` + + // Kerberos configures NFS-Ganesha to secure NFS client connections with Kerberos. + // +optional + // +nullable + Kerberos *KerberosSpec `json:"kerberos,omitempty"` +} + +// KerberosSpec represents configuration for Kerberos. +type KerberosSpec struct { + // PrincipalName corresponds directly to NFS-Ganesha's NFS_KRB5:PrincipalName config. In + // practice, this is the service prefix of the principal name. The default is "nfs". + // This value is combined with (a) the namespace and name of the CephNFS (with a hyphen between) + // and (b) the Realm configured in the user-provided krb5.conf to determine the full principal + // name: /-@. e.g., nfs/rook-ceph-my-nfs@example.net. + // See https://github.com/nfs-ganesha/nfs-ganesha/wiki/RPCSEC_GSS for more detail. + // +optional + // +kubebuilder:default="nfs" + PrincipalName string `json:"principalName"` + + // DomainName should be set to the Kerberos Realm. + // +optional + DomainName string `json:"domainName"` + + // ConfigFiles defines where the Kerberos configuration should be sourced from. Config files + // will be placed into the `/etc/krb5.conf.rook/` directory. + // + // If this is left empty, Rook will not add any files. This allows you to manage the files + // yourself however you wish. For example, you may build them into your custom Ceph container + // image or use the Vault agent injector to securely add the files via annotations on the + // CephNFS spec (passed to the NFS server pods). + // + // Rook configures Kerberos to log to stderr. We suggest removing logging sections from config + // files to avoid consuming unnecessary disk space from logging to files. + // +optional + ConfigFiles KerberosConfigFiles `json:"configFiles"` + + // KeytabFile defines where the Kerberos keytab should be sourced from. The keytab file will be + // placed into `/etc/krb5.keytab`. If this is left empty, Rook will not add the file. + // This allows you to manage the `krb5.keytab` file yourself however you wish. For example, you + // may build it into your custom Ceph container image or use the Vault agent injector to + // securely add the file via annotations on the CephNFS spec (passed to the NFS server pods). + // +optional + KeytabFile KerberosKeytabFile `json:"keytabFile"` +} + +// KerberosConfigFiles represents the source(s) from which Kerberos configuration should come. +type KerberosConfigFiles struct { + // VolumeSource accepts a pared down version of the standard Kubernetes VolumeSource for + // Kerberos configuration files like what is normally used to configure Volumes for a Pod. For + // example, a ConfigMap, Secret, or HostPath. The volume may contain multiple files, all of + // which will be loaded. + VolumeSource *ConfigFileVolumeSource `json:"volumeSource,omitempty"` +} + +// KerberosKeytabFile represents the source(s) from which the Kerberos keytab file should come. +type KerberosKeytabFile struct { + // VolumeSource accepts a pared down version of the standard Kubernetes VolumeSource for the + // Kerberos keytab file like what is normally used to configure Volumes for a Pod. For example, + // a Secret or HostPath. + // There are two requirements for the source's content: + // 1. The config file must be mountable via `subPath: krb5.keytab`. For example, in a + // Secret, the data item must be named `krb5.keytab`, or `items` must be defined to + // select the key and give it path `krb5.keytab`. A HostPath directory must have the + // `krb5.keytab` file. + // 2. The volume or config file must have mode 0600. + VolumeSource *ConfigFileVolumeSource `json:"volumeSource,omitempty"` +} + +// SSSDSpec represents configuration for System Security Services Daemon (SSSD). +type SSSDSpec struct { + // Sidecar tells Rook to run SSSD in a sidecar alongside the NFS-Ganesha server in each NFS pod. + // +optional + Sidecar *SSSDSidecar `json:"sidecar,omitempty"` +} + +// SSSDSidecar represents configuration when SSSD is run in a sidecar. +type SSSDSidecar struct { + // Image defines the container image that should be used for the SSSD sidecar. + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 + Image string `json:"image"` + + // SSSDConfigFile defines where the SSSD configuration should be sourced from. The config file + // will be placed into `/etc/sssd/sssd.conf`. If this is left empty, Rook will not add the file. + // This allows you to manage the `sssd.conf` file yourself however you wish. For example, you + // may build it into your custom Ceph container image or use the Vault agent injector to + // securely add the file via annotations on the CephNFS spec (passed to the NFS server pods). + // +optional + SSSDConfigFile SSSDSidecarConfigFile `json:"sssdConfigFile"` + + // AdditionalFiles defines any number of additional files that should be mounted into the SSSD + // sidecar. These files may be referenced by the sssd.conf config file. + // +optional + AdditionalFiles []SSSDSidecarAdditionalFile `json:"additionalFiles,omitempty"` + + // Resources allow specifying resource requests/limits on the SSSD sidecar container. + // +optional + Resources v1.ResourceRequirements `json:"resources,omitempty"` + + // DebugLevel sets the debug level for SSSD. If unset or set to 0, Rook does nothing. Otherwise, + // this may be a value between 1 and 10. See SSSD docs for more info: + // https://sssd.io/troubleshooting/basics.html#sssd-debug-logs + // +optional + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=10 + DebugLevel int `json:"debugLevel,omitempty"` +} + +// SSSDSidecarConfigFile represents the source(s) from which the SSSD configuration should come. +type SSSDSidecarConfigFile struct { + // VolumeSource accepts a pared down version of the standard Kubernetes VolumeSource for the + // SSSD configuration file like what is normally used to configure Volumes for a Pod. For + // example, a ConfigMap, Secret, or HostPath. There are two requirements for the source's + // content: + // 1. The config file must be mountable via `subPath: sssd.conf`. For example, in a ConfigMap, + // the data item must be named `sssd.conf`, or `items` must be defined to select the key + // and give it path `sssd.conf`. A HostPath directory must have the `sssd.conf` file. + // 2. The volume or config file must have mode 0600. + VolumeSource *ConfigFileVolumeSource `json:"volumeSource,omitempty"` +} + +// SSSDSidecarAdditionalFile represents the source from where additional files for the the SSSD +// configuration should come from and are made available. +type SSSDSidecarAdditionalFile struct { + // SubPath defines the sub-path in `/etc/sssd/rook-additional/` where the additional file(s) + // will be placed. Each subPath definition must be unique and must not contain ':'. + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:Pattern=`^[^:]+$` + SubPath string `json:"subPath"` + + // VolumeSource accepts a pared down version of the standard Kubernetes VolumeSource for the + // additional file(s) like what is normally used to configure Volumes for a Pod. Fore example, a + // ConfigMap, Secret, or HostPath. Each VolumeSource adds one or more additional files to the + // SSSD sidecar container in the `/etc/sssd/rook-additional/` directory. + // Be aware that some files may need to have a specific file mode like 0600 due to requirements + // by SSSD for some files. For example, CA or TLS certificates. + VolumeSource *ConfigFileVolumeSource `json:"volumeSource"` +} + +// NetworkSpec for Ceph includes backward compatibility code +// +kubebuilder:validation:XValidation:message="at least one network selector must be specified when using multus",rule="!has(self.provider) || (self.provider != 'multus' || (self.provider == 'multus' && size(self.selectors) > 0))" +type NetworkSpec struct { + // Provider is what provides network connectivity to the cluster e.g. "host" or "multus" + // +kubebuilder:validation:XValidation:message="network provider must be disabled (reverted to empty string) before a new provider is enabled",rule="self == '' || self == oldSelf" + // +nullable + // +optional + Provider NetworkProviderType `json:"provider,omitempty"` + + // Selectors define NetworkAttachmentDefinitions to be used for Ceph public and/or cluster + // networks when the "multus" network provider is used. This config section is not used for + // other network providers. + // + // Valid keys are "public" and "cluster". Refer to Ceph networking documentation for more: + // https://docs.ceph.com/en/reef/rados/configuration/network-config-ref/ + // + // Refer to Multus network annotation documentation for help selecting values: + // https://github.com/k8snetworkplumbingwg/multus-cni/blob/master/docs/how-to-use.md#run-pod-with-network-annotation + // + // Rook will make a best-effort attempt to automatically detect CIDR address ranges for given + // network attachment definitions. Rook's methods are robust but may be imprecise for + // sufficiently complicated networks. Rook's auto-detection process obtains a new IP address + // lease for each CephCluster reconcile. If Rook fails to detect, incorrectly detects, only + // partially detects, or if underlying networks do not support reusing old IP addresses, it is + // best to use the 'addressRanges' config section to specify CIDR ranges for the Ceph cluster. + // + // As a contrived example, one can use a theoretical Kubernetes-wide network for Ceph client + // traffic and a theoretical Rook-only network for Ceph replication traffic as shown: + // selectors: + // public: "default/cluster-fast-net" + // cluster: "rook-ceph/ceph-backend-net" + // + // +nullable + // +optional + Selectors map[CephNetworkType]string `json:"selectors,omitempty"` + + // AddressRanges specify a list of CIDRs that Rook will apply to Ceph's 'public_network' and/or + // 'cluster_network' configurations. This config section may be used for the "host" or "multus" + // network providers. + // +nullable + // +optional + AddressRanges *AddressRangesSpec `json:"addressRanges,omitempty"` + + // Settings for network connections such as compression and encryption across the + // wire. + // +nullable + // +optional + Connections *ConnectionsSpec `json:"connections,omitempty"` + + // HostNetwork to enable host network + // +optional + HostNetwork bool `json:"hostNetwork,omitempty"` + + // IPFamily is the single stack IPv6 or IPv4 protocol + // +kubebuilder:validation:Enum=IPv4;IPv6 + // +nullable + // +optional + IPFamily IPFamilyType `json:"ipFamily,omitempty"` + + // DualStack determines whether Ceph daemons should listen on both IPv4 and IPv6 + // +optional + DualStack bool `json:"dualStack,omitempty"` + + // Enable multiClusterService to export the Services between peer clusters + // +optional + MultiClusterService MultiClusterServiceSpec `json:"multiClusterService,omitempty"` +} + +// NetworkProviderType defines valid network providers for Rook. +// +kubebuilder:validation:Enum="";host;multus +type NetworkProviderType string + +const ( + NetworkProviderDefault = NetworkProviderType("") + NetworkProviderHost = NetworkProviderType("host") + NetworkProviderMultus = NetworkProviderType("multus") +) + +// CephNetworkType should be "public" or "cluster". +// Allow any string so that over-specified legacy clusters do not break on CRD update. +type CephNetworkType string + +const ( + CephNetworkPublic = CephNetworkType("public") + CephNetworkCluster = CephNetworkType("cluster") +) + +type AddressRangesSpec struct { + // Public defines a list of CIDRs to use for Ceph public network communication. + // +optional + Public CIDRList `json:"public"` + + // Cluster defines a list of CIDRs to use for Ceph cluster network communication. + // +optional + Cluster CIDRList `json:"cluster"` +} + +// An IPv4 or IPv6 network CIDR. +// +// This naive kubebuilder regex provides immediate feedback for some typos and for a common problem +// case where the range spec is forgotten (e.g., /24). Rook does in-depth validation in code. +// +kubebuilder:validation:Pattern=`^[0-9a-fA-F:.]{2,}\/[0-9]{1,3}$` +type CIDR string + +// A list of CIDRs. +type CIDRList []CIDR + +type MultiClusterServiceSpec struct { + // Enable multiClusterService to export the mon and OSD services to peer cluster. + // Ensure that peer clusters are connected using an MCS API compatible application, + // like Globalnet Submariner. + // +optional + Enabled bool `json:"enabled,omitempty"` + + // ClusterID uniquely identifies a cluster. It is used as a prefix to nslookup exported + // services. For example: ...svc.clusterset.local + ClusterID string `json:"clusterID,omitempty"` +} +type ConnectionsSpec struct { + // Encryption settings for the network connections. + // +nullable + // +optional + Encryption *EncryptionSpec `json:"encryption,omitempty"` + + // Compression settings for the network connections. + // +nullable + // +optional + Compression *CompressionSpec `json:"compression,omitempty"` + + // Whether to require msgr2 (port 3300) even if compression or encryption are not enabled. + // If true, the msgr1 port (6789) will be disabled. + // Requires a kernel that supports msgr2 (kernel 5.11 or CentOS 8.4 or newer). + // +optional + RequireMsgr2 bool `json:"requireMsgr2,omitempty"` +} + +type EncryptionSpec struct { + // Whether to encrypt the data in transit across the wire to prevent eavesdropping + // the data on the network. The default is not set. Even if encryption is not enabled, + // clients still establish a strong initial authentication for the connection + // and data integrity is still validated with a crc check. When encryption is enabled, + // all communication between clients and Ceph daemons, or between Ceph daemons will + // be encrypted. + // +optional + Enabled bool `json:"enabled,omitempty"` +} + +type CompressionSpec struct { + // Whether to compress the data in transit across the wire. + // The default is not set. Requires Ceph Quincy (v17) or newer. + // +optional + Enabled bool `json:"enabled,omitempty"` +} + +// DisruptionManagementSpec configures management of daemon disruptions +type DisruptionManagementSpec struct { + // This enables management of poddisruptionbudgets + // +optional + ManagePodBudgets bool `json:"managePodBudgets,omitempty"` + + // OSDMaintenanceTimeout sets how many additional minutes the DOWN/OUT interval is for drained failure domains + // it only works if managePodBudgets is true. + // the default is 30 minutes + // +optional + OSDMaintenanceTimeout time.Duration `json:"osdMaintenanceTimeout,omitempty"` + + // PGHealthCheckTimeout is the time (in minutes) that the operator will wait for the placement groups to become + // healthy (active+clean) after a drain was completed and OSDs came back up. Rook will continue with the next drain + // if the timeout exceeds. It only works if managePodBudgets is true. + // No values or 0 means that the operator will wait until the placement groups are healthy before unblocking the next drain. + // +optional + PGHealthCheckTimeout time.Duration `json:"pgHealthCheckTimeout,omitempty"` + + // PgHealthyRegex is the regular expression that is used to determine which PG states should be considered healthy. + // The default is `^(active\+clean|active\+clean\+scrubbing|active\+clean\+scrubbing\+deep)$` + // +optional + PGHealthyRegex string `json:"pgHealthyRegex,omitempty"` + + // Deprecated. This enables management of machinedisruptionbudgets. + // +optional + ManageMachineDisruptionBudgets bool `json:"manageMachineDisruptionBudgets,omitempty"` + + // Deprecated. Namespace to look for MDBs by the machineDisruptionBudgetController + // +optional + MachineDisruptionBudgetNamespace string `json:"machineDisruptionBudgetNamespace,omitempty"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephClient represents a Ceph Client +// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase` +// +kubebuilder:subresource:status +type CephClient struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + // Spec represents the specification of a Ceph Client + Spec ClientSpec `json:"spec"` + // Status represents the status of a Ceph Client + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Status *CephClientStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephClientList represents a list of Ceph Clients +type CephClientList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephClient `json:"items"` +} + +// ClientSpec represents the specification of a Ceph Client +type ClientSpec struct { + // +optional + Name string `json:"name,omitempty"` + // +kubebuilder:pruning:PreserveUnknownFields + Caps map[string]string `json:"caps"` +} + +// CephClientStatus represents the Status of Ceph Client +type CephClientStatus struct { + // +optional + Phase ConditionType `json:"phase,omitempty"` + // +optional + // +nullable + Info map[string]string `json:"info,omitempty"` + // ObservedGeneration is the latest generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` +} + +// CleanupPolicySpec represents a Ceph Cluster cleanup policy +type CleanupPolicySpec struct { + // Confirmation represents the cleanup confirmation + // +optional + // +nullable + Confirmation CleanupConfirmationProperty `json:"confirmation,omitempty"` + // SanitizeDisks represents way we sanitize disks + // +optional + // +nullable + SanitizeDisks SanitizeDisksSpec `json:"sanitizeDisks,omitempty"` + // AllowUninstallWithVolumes defines whether we can proceed with the uninstall if they are RBD images still present + // +optional + AllowUninstallWithVolumes bool `json:"allowUninstallWithVolumes,omitempty"` +} + +// CleanupConfirmationProperty represents the cleanup confirmation +// +kubebuilder:validation:Pattern=`^$|^yes-really-destroy-data$` +type CleanupConfirmationProperty string + +// SanitizeDataSourceProperty represents a sanitizing data source +type SanitizeDataSourceProperty string + +// SanitizeMethodProperty represents a disk sanitizing method +type SanitizeMethodProperty string + +// SanitizeDisksSpec represents a disk sanitizing specification +type SanitizeDisksSpec struct { + // Method is the method we use to sanitize disks + // +optional + // +kubebuilder:validation:Enum=complete;quick + Method SanitizeMethodProperty `json:"method,omitempty"` + // DataSource is the data source to use to sanitize the disk with + // +optional + // +kubebuilder:validation:Enum=zero;random + DataSource SanitizeDataSourceProperty `json:"dataSource,omitempty"` + // Iteration is the number of pass to apply the sanitizing + // +optional + Iteration int32 `json:"iteration,omitempty"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephRBDMirror represents a Ceph RBD Mirror +// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase` +// +kubebuilder:subresource:status +type CephRBDMirror struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + Spec RBDMirroringSpec `json:"spec"` + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Status *Status `json:"status,omitempty"` +} + +// CephRBDMirrorList represents a list Ceph RBD Mirrors +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type CephRBDMirrorList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephRBDMirror `json:"items"` +} + +// RBDMirroringSpec represents the specification of an RBD mirror daemon +type RBDMirroringSpec struct { + // Count represents the number of rbd mirror instance to run + // +kubebuilder:validation:Minimum=1 + Count int `json:"count"` + + // Peers represents the peers spec + // +nullable + // +optional + Peers MirroringPeerSpec `json:"peers,omitempty"` + + // The affinity to place the rgw pods (default is to place on any available node) + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Placement Placement `json:"placement,omitempty"` + + // The annotations-related configuration to add/set on each Pod related object. + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Annotations Annotations `json:"annotations,omitempty"` + + // The labels-related configuration to add/set on each Pod related object. + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Labels Labels `json:"labels,omitempty"` + + // The resource requirements for the rbd mirror pods + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Resources v1.ResourceRequirements `json:"resources,omitempty"` + + // PriorityClassName sets priority class on the rbd mirror pods + // +optional + PriorityClassName string `json:"priorityClassName,omitempty"` +} + +// MirroringPeerSpec represents the specification of a mirror peer +type MirroringPeerSpec struct { + // SecretNames represents the Kubernetes Secret names to add rbd-mirror or cephfs-mirror peers + // +optional + SecretNames []string `json:"secretNames,omitempty"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephFilesystemMirror is the Ceph Filesystem Mirror object definition +// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase` +// +kubebuilder:subresource:status +type CephFilesystemMirror struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + Spec FilesystemMirroringSpec `json:"spec"` + // +optional + Status *Status `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephFilesystemMirrorList is a list of CephFilesystemMirror +type CephFilesystemMirrorList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephFilesystemMirror `json:"items"` +} + +// FilesystemMirroringSpec is the filesystem mirroring specification +type FilesystemMirroringSpec struct { + // The affinity to place the rgw pods (default is to place on any available node) + // +nullable + // +optional + Placement Placement `json:"placement,omitempty"` + + // The annotations-related configuration to add/set on each Pod related object. + // +nullable + // +optional + Annotations Annotations `json:"annotations,omitempty"` + + // The labels-related configuration to add/set on each Pod related object. + // +nullable + // +optional + Labels Labels `json:"labels,omitempty"` + + // The resource requirements for the cephfs-mirror pods + // +nullable + // +optional + Resources v1.ResourceRequirements `json:"resources,omitempty"` + + // PriorityClassName sets priority class on the cephfs-mirror pods + // +optional + PriorityClassName string `json:"priorityClassName,omitempty"` +} + +// IPFamilyType represents the single stack Ipv4 or Ipv6 protocol. +type IPFamilyType string + +const ( + // IPv6 internet protocol version + IPv6 IPFamilyType = "IPv6" + // IPv4 internet protocol version + IPv4 IPFamilyType = "IPv4" +) + +type StorageScopeSpec struct { + // +nullable + // +optional + Nodes []Node `json:"nodes,omitempty"` + // +optional + UseAllNodes bool `json:"useAllNodes,omitempty"` + // +optional + OnlyApplyOSDPlacement bool `json:"onlyApplyOSDPlacement,omitempty"` + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Config map[string]string `json:"config,omitempty"` + Selection `json:",inline"` + // +nullable + // +optional + StorageClassDeviceSets []StorageClassDeviceSet `json:"storageClassDeviceSets,omitempty"` + // +optional + Store OSDStore `json:"store,omitempty"` + // +optional + // FlappingRestartIntervalHours defines the time for which the OSD pods, that failed with zero exit code, will sleep before restarting. + // This is needed for OSD flapping where OSD daemons are marked down more than 5 times in 600 seconds by Ceph. + // Preventing the OSD pods to restart immediately in such scenarios will prevent Rook from marking OSD as `up` and thus + // peering of the PGs mapped to the OSD. + // User needs to manually restart the OSD pod if they manage to fix the underlying OSD flapping issue before the restart interval. + // The sleep will be disabled if this interval is set to 0. + FlappingRestartIntervalHours int `json:"flappingRestartIntervalHours"` +} + +// OSDStore is the backend storage type used for creating the OSDs +type OSDStore struct { + // Type of backend storage to be used while creating OSDs. If empty, then bluestore will be used + // +optional + // +kubebuilder:validation:Enum=bluestore;bluestore-rdr; + Type string `json:"type,omitempty"` + // UpdateStore updates the backend store for existing OSDs. It destroys each OSD one at a time, cleans up the backing disk + // and prepares same OSD on that disk + // +optional + // +kubebuilder:validation:Pattern=`^$|^yes-really-update-store$` + UpdateStore string `json:"updateStore,omitempty"` +} + +// Node is a storage nodes +// +nullable +type Node struct { + // +optional + Name string `json:"name,omitempty"` + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Resources v1.ResourceRequirements `json:"resources,omitempty"` + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Config map[string]string `json:"config,omitempty"` + Selection `json:",inline"` +} + +// Device represents a disk to use in the cluster +type Device struct { + // +optional + Name string `json:"name,omitempty"` + // +optional + FullPath string `json:"fullpath,omitempty"` + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Config map[string]string `json:"config,omitempty"` +} + +type Selection struct { + // Whether to consume all the storage devices found on a machine + // +optional + UseAllDevices *bool `json:"useAllDevices,omitempty"` + // A regular expression to allow more fine-grained selection of devices on nodes across the cluster + // +optional + DeviceFilter string `json:"deviceFilter,omitempty"` + // A regular expression to allow more fine-grained selection of devices with path names + // +optional + DevicePathFilter string `json:"devicePathFilter,omitempty"` + // List of devices to use as storage devices + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Devices []Device `json:"devices,omitempty"` + // PersistentVolumeClaims to use as storage + // +optional + VolumeClaimTemplates []v1.PersistentVolumeClaim `json:"volumeClaimTemplates,omitempty"` +} + +// PlacementSpec is the placement for core ceph daemons part of the CephCluster CRD +type PlacementSpec map[KeyType]Placement + +// Placement is the placement for an object +type Placement struct { + // NodeAffinity is a group of node affinity scheduling rules + // +optional + NodeAffinity *v1.NodeAffinity `json:"nodeAffinity,omitempty"` + // PodAffinity is a group of inter pod affinity scheduling rules + // +optional + PodAffinity *v1.PodAffinity `json:"podAffinity,omitempty"` + // PodAntiAffinity is a group of inter pod anti affinity scheduling rules + // +optional + PodAntiAffinity *v1.PodAntiAffinity `json:"podAntiAffinity,omitempty"` + // The pod this Toleration is attached to tolerates any taint that matches + // the triple using the matching operator + // +optional + Tolerations []v1.Toleration `json:"tolerations,omitempty"` + // TopologySpreadConstraint specifies how to spread matching pods among the given topology + // +optional + TopologySpreadConstraints []v1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"` +} + +// ResourceSpec is a collection of ResourceRequirements that describes the compute resource requirements +type ResourceSpec map[string]v1.ResourceRequirements + +// ProbeSpec is a wrapper around Probe so it can be enabled or disabled for a Ceph daemon +type ProbeSpec struct { + // Disabled determines whether probe is disable or not + // +optional + Disabled bool `json:"disabled,omitempty"` + // Probe describes a health check to be performed against a container to determine whether it is + // alive or ready to receive traffic. + // +optional + Probe *v1.Probe `json:"probe,omitempty"` +} + +// PriorityClassNamesSpec is a map of priority class names to be assigned to components +type PriorityClassNamesSpec map[KeyType]string + +// StorageClassDeviceSet is a storage class device set +// +nullable +type StorageClassDeviceSet struct { + // Name is a unique identifier for the set + Name string `json:"name"` + // Count is the number of devices in this set + // +kubebuilder:validation:Minimum=1 + Count int `json:"count"` + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Resources v1.ResourceRequirements `json:"resources,omitempty"` // Requests/limits for the devices + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Placement Placement `json:"placement,omitempty"` // Placement constraints for the device daemons + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + PreparePlacement *Placement `json:"preparePlacement,omitempty"` // Placement constraints for the device preparation + // Provider-specific device configuration + // +kubebuilder:pruning:PreserveUnknownFields + // +nullable + // +optional + Config map[string]string `json:"config,omitempty"` + // VolumeClaimTemplates is a list of PVC templates for the underlying storage devices + VolumeClaimTemplates []v1.PersistentVolumeClaim `json:"volumeClaimTemplates"` + // Portable represents OSD portability across the hosts + // +optional + Portable bool `json:"portable,omitempty"` + // TuneSlowDeviceClass Tune the OSD when running on a slow Device Class + // +optional + TuneSlowDeviceClass bool `json:"tuneDeviceClass,omitempty"` + // TuneFastDeviceClass Tune the OSD when running on a fast Device Class + // +optional + TuneFastDeviceClass bool `json:"tuneFastDeviceClass,omitempty"` + // Scheduler name for OSD pod placement + // +optional + SchedulerName string `json:"schedulerName,omitempty"` + // Whether to encrypt the deviceSet + // +optional + Encrypted bool `json:"encrypted,omitempty"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephFilesystemSubVolumeGroup represents a Ceph Filesystem SubVolumeGroup +// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase` +// +kubebuilder:subresource:status +type CephFilesystemSubVolumeGroup struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + // Spec represents the specification of a Ceph Filesystem SubVolumeGroup + Spec CephFilesystemSubVolumeGroupSpec `json:"spec"` + // Status represents the status of a CephFilesystem SubvolumeGroup + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Status *CephFilesystemSubVolumeGroupStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephFilesystemSubVolumeGroup represents a list of Ceph Clients +type CephFilesystemSubVolumeGroupList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephFilesystemSubVolumeGroup `json:"items"` +} + +// CephFilesystemSubVolumeGroupSpec represents the specification of a Ceph Filesystem SubVolumeGroup +type CephFilesystemSubVolumeGroupSpec struct { + // The name of the subvolume group. If not set, the default is the name of the subvolumeGroup CR. + // +optional + Name string `json:"name,omitempty"` + // FilesystemName is the name of Ceph Filesystem SubVolumeGroup volume name. Typically it's the name of + // the CephFilesystem CR. If not coming from the CephFilesystem CR, it can be retrieved from the + // list of Ceph Filesystem volumes with `ceph fs volume ls`. To learn more about Ceph Filesystem + // abstractions see https://docs.ceph.com/en/latest/cephfs/fs-volumes/#fs-volumes-and-subvolumes + FilesystemName string `json:"filesystemName"` +} + +// CephFilesystemSubVolumeGroupStatus represents the Status of Ceph Filesystem SubVolumeGroup +type CephFilesystemSubVolumeGroupStatus struct { + // +optional + Phase ConditionType `json:"phase,omitempty"` + // +optional + // +nullable + Info map[string]string `json:"info,omitempty"` + // ObservedGeneration is the latest generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephBlockPoolRadosNamespace represents a Ceph BlockPool Rados Namespace +// +kubebuilder:subresource:status +type CephBlockPoolRadosNamespace struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + // Spec represents the specification of a Ceph BlockPool Rados Namespace + Spec CephBlockPoolRadosNamespaceSpec `json:"spec"` + // Status represents the status of a CephBlockPool Rados Namespace + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Status *CephBlockPoolRadosNamespaceStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephBlockPoolRadosNamespaceList represents a list of Ceph BlockPool Rados Namespace +type CephBlockPoolRadosNamespaceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephBlockPoolRadosNamespace `json:"items"` +} + +// CephBlockPoolRadosNamespaceSpec represents the specification of a CephBlockPool Rados Namespace +type CephBlockPoolRadosNamespaceSpec struct { + // BlockPoolName is the name of Ceph BlockPool. Typically it's the name of + // the CephBlockPool CR. + BlockPoolName string `json:"blockPoolName"` +} + +// CephBlockPoolRadosNamespaceStatus represents the Status of Ceph BlockPool +// Rados Namespace +type CephBlockPoolRadosNamespaceStatus struct { + // +optional + Phase ConditionType `json:"phase,omitempty"` + // +optional + // +nullable + Info map[string]string `json:"info,omitempty"` +} + +// Represents the source of a volume to mount. +// Only one of its members may be specified. +// This is a subset of the full Kubernetes API's VolumeSource that is reduced to what is most likely +// to be useful for mounting config files/dirs into Rook pods. +type ConfigFileVolumeSource struct { + // hostPath represents a pre-existing file or directory on the host + // machine that is directly exposed to the container. This is generally + // used for system agents or other privileged things that are allowed + // to see the host machine. Most containers will NOT need this. + // More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + // --- + // +optional + HostPath *v1.HostPathVolumeSource `json:"hostPath,omitempty" protobuf:"bytes,1,opt,name=hostPath"` + // emptyDir represents a temporary directory that shares a pod's lifetime. + // More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + // +optional + EmptyDir *v1.EmptyDirVolumeSource `json:"emptyDir,omitempty" protobuf:"bytes,2,opt,name=emptyDir"` + // secret represents a secret that should populate this volume. + // More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + // +optional + Secret *v1.SecretVolumeSource `json:"secret,omitempty" protobuf:"bytes,6,opt,name=secret"` + // persistentVolumeClaimVolumeSource represents a reference to a + // PersistentVolumeClaim in the same namespace. + // More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + // +optional + PersistentVolumeClaim *v1.PersistentVolumeClaimVolumeSource `json:"persistentVolumeClaim,omitempty" protobuf:"bytes,10,opt,name=persistentVolumeClaim"` + // configMap represents a configMap that should populate this volume + // +optional + ConfigMap *v1.ConfigMapVolumeSource `json:"configMap,omitempty" protobuf:"bytes,19,opt,name=configMap"` + // projected items for all in one resources secrets, configmaps, and downward API + Projected *v1.ProjectedVolumeSource `json:"projected,omitempty" protobuf:"bytes,26,opt,name=projected"` +} + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CephCOSIDriver represents the CRD for the Ceph COSI Driver Deployment +// +kubebuilder:resource:shortName=cephcosi +type CephCOSIDriver struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + // Spec represents the specification of a Ceph COSI Driver + Spec CephCOSIDriverSpec `json:"spec"` +} + +// CephCOSIDriverList represents a list of Ceph COSI Driver +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type CephCOSIDriverList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CephCOSIDriver `json:"items"` +} + +// CephCOSIDriverSpec represents the specification of a Ceph COSI Driver +type CephCOSIDriverSpec struct { + // Image is the container image to run the Ceph COSI driver + // +optional + Image string `json:"image,omitempty"` + // ObjectProvisionerImage is the container image to run the COSI driver sidecar + // +optional + ObjectProvisionerImage string `json:"objectProvisionerImage,omitempty"` + // DeploymentStrategy is the strategy to use to deploy the COSI driver. + // +optional + // +kubebuilder:validation:Enum=Never;Auto;Always + DeploymentStrategy COSIDeploymentStrategy `json:"deploymentStrategy,omitempty"` + // Placement is the placement strategy to use for the COSI driver + // +optional + Placement Placement `json:"placement,omitempty"` + // Resources is the resource requirements for the COSI driver + // +optional + Resources v1.ResourceRequirements `json:"resources,omitempty"` +} + +// COSIDeploymentStrategy represents the strategy to use to deploy the Ceph COSI driver +type COSIDeploymentStrategy string + +const ( + // Never means the Ceph COSI driver will never deployed + COSIDeploymentStrategyNever COSIDeploymentStrategy = "Never" + // Auto means the Ceph COSI driver will be deployed automatically if object store is present + COSIDeploymentStrategyAuto COSIDeploymentStrategy = "Auto" + // Always means the Ceph COSI driver will be deployed even if the object store is not present + COSIDeploymentStrategyAlways COSIDeploymentStrategy = "Always" +) diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/volume.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/volume.go new file mode 100644 index 00000000000..cc959c68aa9 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/volume.go @@ -0,0 +1,50 @@ +/* +Copyright 2023 The Rook Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "reflect" + + corev1 "k8s.io/api/core/v1" +) + +func (src *ConfigFileVolumeSource) ToKubernetesVolumeSource() *corev1.VolumeSource { + if src == nil { + return nil + } + + dst := &corev1.VolumeSource{} + vDst := reflect.ValueOf(dst).Elem() + + tSrc := reflect.TypeOf(*src) + vSrc := reflect.ValueOf(*src) + for _, srcField := range reflect.VisibleFields(tSrc) { + if !srcField.IsExported() { + continue + } + + srcVal := vSrc.FieldByName(srcField.Name) + if srcVal.IsNil() { + continue // don't do anything if the src field is a nil ptr + } + + dstVal := vDst.FieldByName(srcField.Name) + dstVal.Set(srcVal) + } + + return dst +} diff --git a/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..6d7341efead --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go @@ -0,0 +1,4487 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AMQPEndpointSpec) DeepCopyInto(out *AMQPEndpointSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AMQPEndpointSpec. +func (in *AMQPEndpointSpec) DeepCopy() *AMQPEndpointSpec { + if in == nil { + return nil + } + out := new(AMQPEndpointSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AddressRangesSpec) DeepCopyInto(out *AddressRangesSpec) { + *out = *in + if in.Public != nil { + in, out := &in.Public, &out.Public + *out = make(CIDRList, len(*in)) + copy(*out, *in) + } + if in.Cluster != nil { + in, out := &in.Cluster, &out.Cluster + *out = make(CIDRList, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressRangesSpec. +func (in *AddressRangesSpec) DeepCopy() *AddressRangesSpec { + if in == nil { + return nil + } + out := new(AddressRangesSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in Annotations) DeepCopyInto(out *Annotations) { + { + in := &in + *out = make(Annotations, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Annotations. +func (in Annotations) DeepCopy() Annotations { + if in == nil { + return nil + } + out := new(Annotations) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in AnnotationsSpec) DeepCopyInto(out *AnnotationsSpec) { + { + in := &in + *out = make(AnnotationsSpec, len(*in)) + for key, val := range *in { + var outVal map[string]string + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = make(Annotations, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + (*out)[key] = outVal + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnnotationsSpec. +func (in AnnotationsSpec) DeepCopy() AnnotationsSpec { + if in == nil { + return nil + } + out := new(AnnotationsSpec) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BucketNotificationSpec) DeepCopyInto(out *BucketNotificationSpec) { + *out = *in + if in.Events != nil { + in, out := &in.Events, &out.Events + *out = make([]BucketNotificationEvent, len(*in)) + copy(*out, *in) + } + if in.Filter != nil { + in, out := &in.Filter, &out.Filter + *out = new(NotificationFilterSpec) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BucketNotificationSpec. +func (in *BucketNotificationSpec) DeepCopy() *BucketNotificationSpec { + if in == nil { + return nil + } + out := new(BucketNotificationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BucketTopicSpec) DeepCopyInto(out *BucketTopicSpec) { + *out = *in + in.Endpoint.DeepCopyInto(&out.Endpoint) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BucketTopicSpec. +func (in *BucketTopicSpec) DeepCopy() *BucketTopicSpec { + if in == nil { + return nil + } + out := new(BucketTopicSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BucketTopicStatus) DeepCopyInto(out *BucketTopicStatus) { + *out = *in + if in.ARN != nil { + in, out := &in.ARN, &out.ARN + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BucketTopicStatus. +func (in *BucketTopicStatus) DeepCopy() *BucketTopicStatus { + if in == nil { + return nil + } + out := new(BucketTopicStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in CIDRList) DeepCopyInto(out *CIDRList) { + { + in := &in + *out = make(CIDRList, len(*in)) + copy(*out, *in) + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CIDRList. +func (in CIDRList) DeepCopy() CIDRList { + if in == nil { + return nil + } + out := new(CIDRList) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CSICephFSSpec) DeepCopyInto(out *CSICephFSSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CSICephFSSpec. +func (in *CSICephFSSpec) DeepCopy() *CSICephFSSpec { + if in == nil { + return nil + } + out := new(CSICephFSSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CSIDriverSpec) DeepCopyInto(out *CSIDriverSpec) { + *out = *in + in.ReadAffinity.DeepCopyInto(&out.ReadAffinity) + out.CephFS = in.CephFS + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CSIDriverSpec. +func (in *CSIDriverSpec) DeepCopy() *CSIDriverSpec { + if in == nil { + return nil + } + out := new(CSIDriverSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Capacity) DeepCopyInto(out *Capacity) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Capacity. +func (in *Capacity) DeepCopy() *Capacity { + if in == nil { + return nil + } + out := new(Capacity) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephBlockPool) DeepCopyInto(out *CephBlockPool) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(CephBlockPoolStatus) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephBlockPool. +func (in *CephBlockPool) DeepCopy() *CephBlockPool { + if in == nil { + return nil + } + out := new(CephBlockPool) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephBlockPool) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephBlockPoolList) DeepCopyInto(out *CephBlockPoolList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephBlockPool, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephBlockPoolList. +func (in *CephBlockPoolList) DeepCopy() *CephBlockPoolList { + if in == nil { + return nil + } + out := new(CephBlockPoolList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephBlockPoolList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephBlockPoolRadosNamespace) DeepCopyInto(out *CephBlockPoolRadosNamespace) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(CephBlockPoolRadosNamespaceStatus) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephBlockPoolRadosNamespace. +func (in *CephBlockPoolRadosNamespace) DeepCopy() *CephBlockPoolRadosNamespace { + if in == nil { + return nil + } + out := new(CephBlockPoolRadosNamespace) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephBlockPoolRadosNamespace) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephBlockPoolRadosNamespaceList) DeepCopyInto(out *CephBlockPoolRadosNamespaceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephBlockPoolRadosNamespace, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephBlockPoolRadosNamespaceList. +func (in *CephBlockPoolRadosNamespaceList) DeepCopy() *CephBlockPoolRadosNamespaceList { + if in == nil { + return nil + } + out := new(CephBlockPoolRadosNamespaceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephBlockPoolRadosNamespaceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephBlockPoolRadosNamespaceSpec) DeepCopyInto(out *CephBlockPoolRadosNamespaceSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephBlockPoolRadosNamespaceSpec. +func (in *CephBlockPoolRadosNamespaceSpec) DeepCopy() *CephBlockPoolRadosNamespaceSpec { + if in == nil { + return nil + } + out := new(CephBlockPoolRadosNamespaceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephBlockPoolRadosNamespaceStatus) DeepCopyInto(out *CephBlockPoolRadosNamespaceStatus) { + *out = *in + if in.Info != nil { + in, out := &in.Info, &out.Info + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephBlockPoolRadosNamespaceStatus. +func (in *CephBlockPoolRadosNamespaceStatus) DeepCopy() *CephBlockPoolRadosNamespaceStatus { + if in == nil { + return nil + } + out := new(CephBlockPoolRadosNamespaceStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephBlockPoolStatus) DeepCopyInto(out *CephBlockPoolStatus) { + *out = *in + if in.MirroringStatus != nil { + in, out := &in.MirroringStatus, &out.MirroringStatus + *out = new(MirroringStatusSpec) + (*in).DeepCopyInto(*out) + } + if in.MirroringInfo != nil { + in, out := &in.MirroringInfo, &out.MirroringInfo + *out = new(MirroringInfoSpec) + (*in).DeepCopyInto(*out) + } + if in.SnapshotScheduleStatus != nil { + in, out := &in.SnapshotScheduleStatus, &out.SnapshotScheduleStatus + *out = new(SnapshotScheduleStatusSpec) + (*in).DeepCopyInto(*out) + } + if in.Info != nil { + in, out := &in.Info, &out.Info + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephBlockPoolStatus. +func (in *CephBlockPoolStatus) DeepCopy() *CephBlockPoolStatus { + if in == nil { + return nil + } + out := new(CephBlockPoolStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephBucketNotification) DeepCopyInto(out *CephBucketNotification) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(Status) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephBucketNotification. +func (in *CephBucketNotification) DeepCopy() *CephBucketNotification { + if in == nil { + return nil + } + out := new(CephBucketNotification) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephBucketNotification) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephBucketNotificationList) DeepCopyInto(out *CephBucketNotificationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephBucketNotification, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephBucketNotificationList. +func (in *CephBucketNotificationList) DeepCopy() *CephBucketNotificationList { + if in == nil { + return nil + } + out := new(CephBucketNotificationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephBucketNotificationList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephBucketTopic) DeepCopyInto(out *CephBucketTopic) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(BucketTopicStatus) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephBucketTopic. +func (in *CephBucketTopic) DeepCopy() *CephBucketTopic { + if in == nil { + return nil + } + out := new(CephBucketTopic) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephBucketTopic) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephBucketTopicList) DeepCopyInto(out *CephBucketTopicList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephBucketTopic, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephBucketTopicList. +func (in *CephBucketTopicList) DeepCopy() *CephBucketTopicList { + if in == nil { + return nil + } + out := new(CephBucketTopicList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephBucketTopicList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephCOSIDriver) DeepCopyInto(out *CephCOSIDriver) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephCOSIDriver. +func (in *CephCOSIDriver) DeepCopy() *CephCOSIDriver { + if in == nil { + return nil + } + out := new(CephCOSIDriver) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephCOSIDriver) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephCOSIDriverList) DeepCopyInto(out *CephCOSIDriverList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephCOSIDriver, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephCOSIDriverList. +func (in *CephCOSIDriverList) DeepCopy() *CephCOSIDriverList { + if in == nil { + return nil + } + out := new(CephCOSIDriverList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephCOSIDriverList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephCOSIDriverSpec) DeepCopyInto(out *CephCOSIDriverSpec) { + *out = *in + in.Placement.DeepCopyInto(&out.Placement) + in.Resources.DeepCopyInto(&out.Resources) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephCOSIDriverSpec. +func (in *CephCOSIDriverSpec) DeepCopy() *CephCOSIDriverSpec { + if in == nil { + return nil + } + out := new(CephCOSIDriverSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephClient) DeepCopyInto(out *CephClient) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(CephClientStatus) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephClient. +func (in *CephClient) DeepCopy() *CephClient { + if in == nil { + return nil + } + out := new(CephClient) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephClient) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephClientList) DeepCopyInto(out *CephClientList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephClient, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephClientList. +func (in *CephClientList) DeepCopy() *CephClientList { + if in == nil { + return nil + } + out := new(CephClientList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephClientList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephClientStatus) DeepCopyInto(out *CephClientStatus) { + *out = *in + if in.Info != nil { + in, out := &in.Info, &out.Info + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephClientStatus. +func (in *CephClientStatus) DeepCopy() *CephClientStatus { + if in == nil { + return nil + } + out := new(CephClientStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephCluster) DeepCopyInto(out *CephCluster) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephCluster. +func (in *CephCluster) DeepCopy() *CephCluster { + if in == nil { + return nil + } + out := new(CephCluster) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephCluster) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephClusterHealthCheckSpec) DeepCopyInto(out *CephClusterHealthCheckSpec) { + *out = *in + in.DaemonHealth.DeepCopyInto(&out.DaemonHealth) + if in.LivenessProbe != nil { + in, out := &in.LivenessProbe, &out.LivenessProbe + *out = make(map[KeyType]*ProbeSpec, len(*in)) + for key, val := range *in { + var outVal *ProbeSpec + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = new(ProbeSpec) + (*in).DeepCopyInto(*out) + } + (*out)[key] = outVal + } + } + if in.StartupProbe != nil { + in, out := &in.StartupProbe, &out.StartupProbe + *out = make(map[KeyType]*ProbeSpec, len(*in)) + for key, val := range *in { + var outVal *ProbeSpec + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = new(ProbeSpec) + (*in).DeepCopyInto(*out) + } + (*out)[key] = outVal + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephClusterHealthCheckSpec. +func (in *CephClusterHealthCheckSpec) DeepCopy() *CephClusterHealthCheckSpec { + if in == nil { + return nil + } + out := new(CephClusterHealthCheckSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephClusterList) DeepCopyInto(out *CephClusterList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephCluster, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephClusterList. +func (in *CephClusterList) DeepCopy() *CephClusterList { + if in == nil { + return nil + } + out := new(CephClusterList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephClusterList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephDaemonsVersions) DeepCopyInto(out *CephDaemonsVersions) { + *out = *in + if in.Mon != nil { + in, out := &in.Mon, &out.Mon + *out = make(map[string]int, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Mgr != nil { + in, out := &in.Mgr, &out.Mgr + *out = make(map[string]int, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Osd != nil { + in, out := &in.Osd, &out.Osd + *out = make(map[string]int, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Rgw != nil { + in, out := &in.Rgw, &out.Rgw + *out = make(map[string]int, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Mds != nil { + in, out := &in.Mds, &out.Mds + *out = make(map[string]int, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.RbdMirror != nil { + in, out := &in.RbdMirror, &out.RbdMirror + *out = make(map[string]int, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.CephFSMirror != nil { + in, out := &in.CephFSMirror, &out.CephFSMirror + *out = make(map[string]int, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Overall != nil { + in, out := &in.Overall, &out.Overall + *out = make(map[string]int, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephDaemonsVersions. +func (in *CephDaemonsVersions) DeepCopy() *CephDaemonsVersions { + if in == nil { + return nil + } + out := new(CephDaemonsVersions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephFilesystem) DeepCopyInto(out *CephFilesystem) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(CephFilesystemStatus) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephFilesystem. +func (in *CephFilesystem) DeepCopy() *CephFilesystem { + if in == nil { + return nil + } + out := new(CephFilesystem) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephFilesystem) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephFilesystemList) DeepCopyInto(out *CephFilesystemList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephFilesystem, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephFilesystemList. +func (in *CephFilesystemList) DeepCopy() *CephFilesystemList { + if in == nil { + return nil + } + out := new(CephFilesystemList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephFilesystemList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephFilesystemMirror) DeepCopyInto(out *CephFilesystemMirror) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(Status) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephFilesystemMirror. +func (in *CephFilesystemMirror) DeepCopy() *CephFilesystemMirror { + if in == nil { + return nil + } + out := new(CephFilesystemMirror) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephFilesystemMirror) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephFilesystemMirrorList) DeepCopyInto(out *CephFilesystemMirrorList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephFilesystemMirror, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephFilesystemMirrorList. +func (in *CephFilesystemMirrorList) DeepCopy() *CephFilesystemMirrorList { + if in == nil { + return nil + } + out := new(CephFilesystemMirrorList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephFilesystemMirrorList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephFilesystemStatus) DeepCopyInto(out *CephFilesystemStatus) { + *out = *in + if in.SnapshotScheduleStatus != nil { + in, out := &in.SnapshotScheduleStatus, &out.SnapshotScheduleStatus + *out = new(FilesystemSnapshotScheduleStatusSpec) + (*in).DeepCopyInto(*out) + } + if in.Info != nil { + in, out := &in.Info, &out.Info + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.MirroringStatus != nil { + in, out := &in.MirroringStatus, &out.MirroringStatus + *out = new(FilesystemMirroringInfoSpec) + (*in).DeepCopyInto(*out) + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephFilesystemStatus. +func (in *CephFilesystemStatus) DeepCopy() *CephFilesystemStatus { + if in == nil { + return nil + } + out := new(CephFilesystemStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephFilesystemSubVolumeGroup) DeepCopyInto(out *CephFilesystemSubVolumeGroup) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(CephFilesystemSubVolumeGroupStatus) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephFilesystemSubVolumeGroup. +func (in *CephFilesystemSubVolumeGroup) DeepCopy() *CephFilesystemSubVolumeGroup { + if in == nil { + return nil + } + out := new(CephFilesystemSubVolumeGroup) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephFilesystemSubVolumeGroup) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephFilesystemSubVolumeGroupList) DeepCopyInto(out *CephFilesystemSubVolumeGroupList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephFilesystemSubVolumeGroup, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephFilesystemSubVolumeGroupList. +func (in *CephFilesystemSubVolumeGroupList) DeepCopy() *CephFilesystemSubVolumeGroupList { + if in == nil { + return nil + } + out := new(CephFilesystemSubVolumeGroupList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephFilesystemSubVolumeGroupList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephFilesystemSubVolumeGroupSpec) DeepCopyInto(out *CephFilesystemSubVolumeGroupSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephFilesystemSubVolumeGroupSpec. +func (in *CephFilesystemSubVolumeGroupSpec) DeepCopy() *CephFilesystemSubVolumeGroupSpec { + if in == nil { + return nil + } + out := new(CephFilesystemSubVolumeGroupSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephFilesystemSubVolumeGroupStatus) DeepCopyInto(out *CephFilesystemSubVolumeGroupStatus) { + *out = *in + if in.Info != nil { + in, out := &in.Info, &out.Info + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephFilesystemSubVolumeGroupStatus. +func (in *CephFilesystemSubVolumeGroupStatus) DeepCopy() *CephFilesystemSubVolumeGroupStatus { + if in == nil { + return nil + } + out := new(CephFilesystemSubVolumeGroupStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephHealthMessage) DeepCopyInto(out *CephHealthMessage) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephHealthMessage. +func (in *CephHealthMessage) DeepCopy() *CephHealthMessage { + if in == nil { + return nil + } + out := new(CephHealthMessage) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephNFS) DeepCopyInto(out *CephNFS) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(Status) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephNFS. +func (in *CephNFS) DeepCopy() *CephNFS { + if in == nil { + return nil + } + out := new(CephNFS) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephNFS) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephNFSList) DeepCopyInto(out *CephNFSList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephNFS, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephNFSList. +func (in *CephNFSList) DeepCopy() *CephNFSList { + if in == nil { + return nil + } + out := new(CephNFSList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephNFSList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephObjectRealm) DeepCopyInto(out *CephObjectRealm) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(Status) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephObjectRealm. +func (in *CephObjectRealm) DeepCopy() *CephObjectRealm { + if in == nil { + return nil + } + out := new(CephObjectRealm) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephObjectRealm) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephObjectRealmList) DeepCopyInto(out *CephObjectRealmList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephObjectRealm, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephObjectRealmList. +func (in *CephObjectRealmList) DeepCopy() *CephObjectRealmList { + if in == nil { + return nil + } + out := new(CephObjectRealmList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephObjectRealmList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephObjectStore) DeepCopyInto(out *CephObjectStore) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(ObjectStoreStatus) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephObjectStore. +func (in *CephObjectStore) DeepCopy() *CephObjectStore { + if in == nil { + return nil + } + out := new(CephObjectStore) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephObjectStore) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephObjectStoreList) DeepCopyInto(out *CephObjectStoreList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephObjectStore, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephObjectStoreList. +func (in *CephObjectStoreList) DeepCopy() *CephObjectStoreList { + if in == nil { + return nil + } + out := new(CephObjectStoreList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephObjectStoreList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephObjectStoreUser) DeepCopyInto(out *CephObjectStoreUser) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(ObjectStoreUserStatus) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephObjectStoreUser. +func (in *CephObjectStoreUser) DeepCopy() *CephObjectStoreUser { + if in == nil { + return nil + } + out := new(CephObjectStoreUser) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephObjectStoreUser) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephObjectStoreUserList) DeepCopyInto(out *CephObjectStoreUserList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephObjectStoreUser, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephObjectStoreUserList. +func (in *CephObjectStoreUserList) DeepCopy() *CephObjectStoreUserList { + if in == nil { + return nil + } + out := new(CephObjectStoreUserList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephObjectStoreUserList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephObjectZone) DeepCopyInto(out *CephObjectZone) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(Status) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephObjectZone. +func (in *CephObjectZone) DeepCopy() *CephObjectZone { + if in == nil { + return nil + } + out := new(CephObjectZone) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephObjectZone) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephObjectZoneGroup) DeepCopyInto(out *CephObjectZoneGroup) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(Status) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephObjectZoneGroup. +func (in *CephObjectZoneGroup) DeepCopy() *CephObjectZoneGroup { + if in == nil { + return nil + } + out := new(CephObjectZoneGroup) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephObjectZoneGroup) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephObjectZoneGroupList) DeepCopyInto(out *CephObjectZoneGroupList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephObjectZoneGroup, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephObjectZoneGroupList. +func (in *CephObjectZoneGroupList) DeepCopy() *CephObjectZoneGroupList { + if in == nil { + return nil + } + out := new(CephObjectZoneGroupList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephObjectZoneGroupList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephObjectZoneList) DeepCopyInto(out *CephObjectZoneList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephObjectZone, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephObjectZoneList. +func (in *CephObjectZoneList) DeepCopy() *CephObjectZoneList { + if in == nil { + return nil + } + out := new(CephObjectZoneList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephObjectZoneList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephRBDMirror) DeepCopyInto(out *CephRBDMirror) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(Status) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephRBDMirror. +func (in *CephRBDMirror) DeepCopy() *CephRBDMirror { + if in == nil { + return nil + } + out := new(CephRBDMirror) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephRBDMirror) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephRBDMirrorList) DeepCopyInto(out *CephRBDMirrorList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CephRBDMirror, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephRBDMirrorList. +func (in *CephRBDMirrorList) DeepCopy() *CephRBDMirrorList { + if in == nil { + return nil + } + out := new(CephRBDMirrorList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CephRBDMirrorList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephStatus) DeepCopyInto(out *CephStatus) { + *out = *in + if in.Details != nil { + in, out := &in.Details, &out.Details + *out = make(map[string]CephHealthMessage, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + out.Capacity = in.Capacity + if in.Versions != nil { + in, out := &in.Versions, &out.Versions + *out = new(CephDaemonsVersions) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephStatus. +func (in *CephStatus) DeepCopy() *CephStatus { + if in == nil { + return nil + } + out := new(CephStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephStorage) DeepCopyInto(out *CephStorage) { + *out = *in + if in.DeviceClasses != nil { + in, out := &in.DeviceClasses, &out.DeviceClasses + *out = make([]DeviceClasses, len(*in)) + copy(*out, *in) + } + in.OSD.DeepCopyInto(&out.OSD) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephStorage. +func (in *CephStorage) DeepCopy() *CephStorage { + if in == nil { + return nil + } + out := new(CephStorage) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CephVersionSpec) DeepCopyInto(out *CephVersionSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CephVersionSpec. +func (in *CephVersionSpec) DeepCopy() *CephVersionSpec { + if in == nil { + return nil + } + out := new(CephVersionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CleanupPolicySpec) DeepCopyInto(out *CleanupPolicySpec) { + *out = *in + out.SanitizeDisks = in.SanitizeDisks + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CleanupPolicySpec. +func (in *CleanupPolicySpec) DeepCopy() *CleanupPolicySpec { + if in == nil { + return nil + } + out := new(CleanupPolicySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClientSpec) DeepCopyInto(out *ClientSpec) { + *out = *in + if in.Caps != nil { + in, out := &in.Caps, &out.Caps + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientSpec. +func (in *ClientSpec) DeepCopy() *ClientSpec { + if in == nil { + return nil + } + out := new(ClientSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { + *out = *in + out.CephVersion = in.CephVersion + in.Storage.DeepCopyInto(&out.Storage) + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(AnnotationsSpec, len(*in)) + for key, val := range *in { + var outVal map[string]string + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = make(Annotations, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + (*out)[key] = outVal + } + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(LabelsSpec, len(*in)) + for key, val := range *in { + var outVal map[string]string + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = make(Labels, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + (*out)[key] = outVal + } + } + if in.Placement != nil { + in, out := &in.Placement, &out.Placement + *out = make(PlacementSpec, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + in.Network.DeepCopyInto(&out.Network) + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = make(ResourceSpec, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + if in.PriorityClassNames != nil { + in, out := &in.PriorityClassNames, &out.PriorityClassNames + *out = make(PriorityClassNamesSpec, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + out.DisruptionManagement = in.DisruptionManagement + in.Mon.DeepCopyInto(&out.Mon) + out.CrashCollector = in.CrashCollector + out.Dashboard = in.Dashboard + in.Monitoring.DeepCopyInto(&out.Monitoring) + out.External = in.External + in.Mgr.DeepCopyInto(&out.Mgr) + out.CleanupPolicy = in.CleanupPolicy + in.HealthCheck.DeepCopyInto(&out.HealthCheck) + in.Security.DeepCopyInto(&out.Security) + in.LogCollector.DeepCopyInto(&out.LogCollector) + in.CSI.DeepCopyInto(&out.CSI) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec. +func (in *ClusterSpec) DeepCopy() *ClusterSpec { + if in == nil { + return nil + } + out := new(ClusterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.CephStatus != nil { + in, out := &in.CephStatus, &out.CephStatus + *out = new(CephStatus) + (*in).DeepCopyInto(*out) + } + if in.CephStorage != nil { + in, out := &in.CephStorage, &out.CephStorage + *out = new(CephStorage) + (*in).DeepCopyInto(*out) + } + if in.CephVersion != nil { + in, out := &in.CephVersion, &out.CephVersion + *out = new(ClusterVersion) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus. +func (in *ClusterStatus) DeepCopy() *ClusterStatus { + if in == nil { + return nil + } + out := new(ClusterStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterVersion) DeepCopyInto(out *ClusterVersion) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterVersion. +func (in *ClusterVersion) DeepCopy() *ClusterVersion { + if in == nil { + return nil + } + out := new(ClusterVersion) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CompressionSpec) DeepCopyInto(out *CompressionSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CompressionSpec. +func (in *CompressionSpec) DeepCopy() *CompressionSpec { + if in == nil { + return nil + } + out := new(CompressionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Condition) DeepCopyInto(out *Condition) { + *out = *in + in.LastHeartbeatTime.DeepCopyInto(&out.LastHeartbeatTime) + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition. +func (in *Condition) DeepCopy() *Condition { + if in == nil { + return nil + } + out := new(Condition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigFileVolumeSource) DeepCopyInto(out *ConfigFileVolumeSource) { + *out = *in + if in.HostPath != nil { + in, out := &in.HostPath, &out.HostPath + *out = new(corev1.HostPathVolumeSource) + (*in).DeepCopyInto(*out) + } + if in.EmptyDir != nil { + in, out := &in.EmptyDir, &out.EmptyDir + *out = new(corev1.EmptyDirVolumeSource) + (*in).DeepCopyInto(*out) + } + if in.Secret != nil { + in, out := &in.Secret, &out.Secret + *out = new(corev1.SecretVolumeSource) + (*in).DeepCopyInto(*out) + } + if in.PersistentVolumeClaim != nil { + in, out := &in.PersistentVolumeClaim, &out.PersistentVolumeClaim + *out = new(corev1.PersistentVolumeClaimVolumeSource) + **out = **in + } + if in.ConfigMap != nil { + in, out := &in.ConfigMap, &out.ConfigMap + *out = new(corev1.ConfigMapVolumeSource) + (*in).DeepCopyInto(*out) + } + if in.Projected != nil { + in, out := &in.Projected, &out.Projected + *out = new(corev1.ProjectedVolumeSource) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigFileVolumeSource. +func (in *ConfigFileVolumeSource) DeepCopy() *ConfigFileVolumeSource { + if in == nil { + return nil + } + out := new(ConfigFileVolumeSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConnectionsSpec) DeepCopyInto(out *ConnectionsSpec) { + *out = *in + if in.Encryption != nil { + in, out := &in.Encryption, &out.Encryption + *out = new(EncryptionSpec) + **out = **in + } + if in.Compression != nil { + in, out := &in.Compression, &out.Compression + *out = new(CompressionSpec) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionsSpec. +func (in *ConnectionsSpec) DeepCopy() *ConnectionsSpec { + if in == nil { + return nil + } + out := new(ConnectionsSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CrashCollectorSpec) DeepCopyInto(out *CrashCollectorSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CrashCollectorSpec. +func (in *CrashCollectorSpec) DeepCopy() *CrashCollectorSpec { + if in == nil { + return nil + } + out := new(CrashCollectorSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DaemonHealthSpec) DeepCopyInto(out *DaemonHealthSpec) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + in.Monitor.DeepCopyInto(&out.Monitor) + in.ObjectStorageDaemon.DeepCopyInto(&out.ObjectStorageDaemon) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DaemonHealthSpec. +func (in *DaemonHealthSpec) DeepCopy() *DaemonHealthSpec { + if in == nil { + return nil + } + out := new(DaemonHealthSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DashboardSpec) DeepCopyInto(out *DashboardSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardSpec. +func (in *DashboardSpec) DeepCopy() *DashboardSpec { + if in == nil { + return nil + } + out := new(DashboardSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Device) DeepCopyInto(out *Device) { + *out = *in + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Device. +func (in *Device) DeepCopy() *Device { + if in == nil { + return nil + } + out := new(Device) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeviceClasses) DeepCopyInto(out *DeviceClasses) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeviceClasses. +func (in *DeviceClasses) DeepCopy() *DeviceClasses { + if in == nil { + return nil + } + out := new(DeviceClasses) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DisruptionManagementSpec) DeepCopyInto(out *DisruptionManagementSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DisruptionManagementSpec. +func (in *DisruptionManagementSpec) DeepCopy() *DisruptionManagementSpec { + if in == nil { + return nil + } + out := new(DisruptionManagementSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EncryptionSpec) DeepCopyInto(out *EncryptionSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EncryptionSpec. +func (in *EncryptionSpec) DeepCopy() *EncryptionSpec { + if in == nil { + return nil + } + out := new(EncryptionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EndpointAddress) DeepCopyInto(out *EndpointAddress) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointAddress. +func (in *EndpointAddress) DeepCopy() *EndpointAddress { + if in == nil { + return nil + } + out := new(EndpointAddress) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ErasureCodedSpec) DeepCopyInto(out *ErasureCodedSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ErasureCodedSpec. +func (in *ErasureCodedSpec) DeepCopy() *ErasureCodedSpec { + if in == nil { + return nil + } + out := new(ErasureCodedSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalSpec) DeepCopyInto(out *ExternalSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSpec. +func (in *ExternalSpec) DeepCopy() *ExternalSpec { + if in == nil { + return nil + } + out := new(ExternalSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FSMirroringSpec) DeepCopyInto(out *FSMirroringSpec) { + *out = *in + if in.Peers != nil { + in, out := &in.Peers, &out.Peers + *out = new(MirroringPeerSpec) + (*in).DeepCopyInto(*out) + } + if in.SnapshotSchedules != nil { + in, out := &in.SnapshotSchedules, &out.SnapshotSchedules + *out = make([]SnapshotScheduleSpec, len(*in)) + copy(*out, *in) + } + if in.SnapshotRetention != nil { + in, out := &in.SnapshotRetention, &out.SnapshotRetention + *out = make([]SnapshotScheduleRetentionSpec, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FSMirroringSpec. +func (in *FSMirroringSpec) DeepCopy() *FSMirroringSpec { + if in == nil { + return nil + } + out := new(FSMirroringSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FilesystemMirrorInfoPeerSpec) DeepCopyInto(out *FilesystemMirrorInfoPeerSpec) { + *out = *in + if in.Remote != nil { + in, out := &in.Remote, &out.Remote + *out = new(PeerRemoteSpec) + **out = **in + } + if in.Stats != nil { + in, out := &in.Stats, &out.Stats + *out = new(PeerStatSpec) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FilesystemMirrorInfoPeerSpec. +func (in *FilesystemMirrorInfoPeerSpec) DeepCopy() *FilesystemMirrorInfoPeerSpec { + if in == nil { + return nil + } + out := new(FilesystemMirrorInfoPeerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FilesystemMirroringInfo) DeepCopyInto(out *FilesystemMirroringInfo) { + *out = *in + if in.Filesystems != nil { + in, out := &in.Filesystems, &out.Filesystems + *out = make([]FilesystemsSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FilesystemMirroringInfo. +func (in *FilesystemMirroringInfo) DeepCopy() *FilesystemMirroringInfo { + if in == nil { + return nil + } + out := new(FilesystemMirroringInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FilesystemMirroringInfoSpec) DeepCopyInto(out *FilesystemMirroringInfoSpec) { + *out = *in + if in.FilesystemMirroringAllInfo != nil { + in, out := &in.FilesystemMirroringAllInfo, &out.FilesystemMirroringAllInfo + *out = make([]FilesystemMirroringInfo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FilesystemMirroringInfoSpec. +func (in *FilesystemMirroringInfoSpec) DeepCopy() *FilesystemMirroringInfoSpec { + if in == nil { + return nil + } + out := new(FilesystemMirroringInfoSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FilesystemMirroringSpec) DeepCopyInto(out *FilesystemMirroringSpec) { + *out = *in + in.Placement.DeepCopyInto(&out.Placement) + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(Annotations, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(Labels, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.Resources.DeepCopyInto(&out.Resources) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FilesystemMirroringSpec. +func (in *FilesystemMirroringSpec) DeepCopy() *FilesystemMirroringSpec { + if in == nil { + return nil + } + out := new(FilesystemMirroringSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FilesystemSnapshotScheduleStatusRetention) DeepCopyInto(out *FilesystemSnapshotScheduleStatusRetention) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FilesystemSnapshotScheduleStatusRetention. +func (in *FilesystemSnapshotScheduleStatusRetention) DeepCopy() *FilesystemSnapshotScheduleStatusRetention { + if in == nil { + return nil + } + out := new(FilesystemSnapshotScheduleStatusRetention) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FilesystemSnapshotScheduleStatusSpec) DeepCopyInto(out *FilesystemSnapshotScheduleStatusSpec) { + *out = *in + if in.SnapshotSchedules != nil { + in, out := &in.SnapshotSchedules, &out.SnapshotSchedules + *out = make([]FilesystemSnapshotSchedulesSpec, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FilesystemSnapshotScheduleStatusSpec. +func (in *FilesystemSnapshotScheduleStatusSpec) DeepCopy() *FilesystemSnapshotScheduleStatusSpec { + if in == nil { + return nil + } + out := new(FilesystemSnapshotScheduleStatusSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FilesystemSnapshotSchedulesSpec) DeepCopyInto(out *FilesystemSnapshotSchedulesSpec) { + *out = *in + out.Retention = in.Retention + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FilesystemSnapshotSchedulesSpec. +func (in *FilesystemSnapshotSchedulesSpec) DeepCopy() *FilesystemSnapshotSchedulesSpec { + if in == nil { + return nil + } + out := new(FilesystemSnapshotSchedulesSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FilesystemSpec) DeepCopyInto(out *FilesystemSpec) { + *out = *in + in.MetadataPool.DeepCopyInto(&out.MetadataPool) + if in.DataPools != nil { + in, out := &in.DataPools, &out.DataPools + *out = make([]NamedPoolSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.MetadataServer.DeepCopyInto(&out.MetadataServer) + if in.Mirroring != nil { + in, out := &in.Mirroring, &out.Mirroring + *out = new(FSMirroringSpec) + (*in).DeepCopyInto(*out) + } + in.StatusCheck.DeepCopyInto(&out.StatusCheck) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FilesystemSpec. +func (in *FilesystemSpec) DeepCopy() *FilesystemSpec { + if in == nil { + return nil + } + out := new(FilesystemSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FilesystemsSpec) DeepCopyInto(out *FilesystemsSpec) { + *out = *in + if in.Peers != nil { + in, out := &in.Peers, &out.Peers + *out = make([]FilesystemMirrorInfoPeerSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FilesystemsSpec. +func (in *FilesystemsSpec) DeepCopy() *FilesystemsSpec { + if in == nil { + return nil + } + out := new(FilesystemsSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GaneshaRADOSSpec) DeepCopyInto(out *GaneshaRADOSSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GaneshaRADOSSpec. +func (in *GaneshaRADOSSpec) DeepCopy() *GaneshaRADOSSpec { + if in == nil { + return nil + } + out := new(GaneshaRADOSSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GaneshaServerSpec) DeepCopyInto(out *GaneshaServerSpec) { + *out = *in + in.Placement.DeepCopyInto(&out.Placement) + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(Annotations, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(Labels, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.Resources.DeepCopyInto(&out.Resources) + if in.HostNetwork != nil { + in, out := &in.HostNetwork, &out.HostNetwork + *out = new(bool) + **out = **in + } + if in.LivenessProbe != nil { + in, out := &in.LivenessProbe, &out.LivenessProbe + *out = new(ProbeSpec) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GaneshaServerSpec. +func (in *GaneshaServerSpec) DeepCopy() *GaneshaServerSpec { + if in == nil { + return nil + } + out := new(GaneshaServerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GatewaySpec) DeepCopyInto(out *GatewaySpec) { + *out = *in + in.Placement.DeepCopyInto(&out.Placement) + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(Annotations, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(Labels, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.Resources.DeepCopyInto(&out.Resources) + if in.ExternalRgwEndpoints != nil { + in, out := &in.ExternalRgwEndpoints, &out.ExternalRgwEndpoints + *out = make([]EndpointAddress, len(*in)) + copy(*out, *in) + } + if in.Service != nil { + in, out := &in.Service, &out.Service + *out = new(RGWServiceSpec) + (*in).DeepCopyInto(*out) + } + if in.HostNetwork != nil { + in, out := &in.HostNetwork, &out.HostNetwork + *out = new(bool) + **out = **in + } + if in.DashboardEnabled != nil { + in, out := &in.DashboardEnabled, &out.DashboardEnabled + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewaySpec. +func (in *GatewaySpec) DeepCopy() *GatewaySpec { + if in == nil { + return nil + } + out := new(GatewaySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HTTPEndpointSpec) DeepCopyInto(out *HTTPEndpointSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPEndpointSpec. +func (in *HTTPEndpointSpec) DeepCopy() *HTTPEndpointSpec { + if in == nil { + return nil + } + out := new(HTTPEndpointSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HealthCheckSpec) DeepCopyInto(out *HealthCheckSpec) { + *out = *in + if in.Interval != nil { + in, out := &in.Interval, &out.Interval + *out = new(metav1.Duration) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthCheckSpec. +func (in *HealthCheckSpec) DeepCopy() *HealthCheckSpec { + if in == nil { + return nil + } + out := new(HealthCheckSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HybridStorageSpec) DeepCopyInto(out *HybridStorageSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HybridStorageSpec. +func (in *HybridStorageSpec) DeepCopy() *HybridStorageSpec { + if in == nil { + return nil + } + out := new(HybridStorageSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KafkaEndpointSpec) DeepCopyInto(out *KafkaEndpointSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KafkaEndpointSpec. +func (in *KafkaEndpointSpec) DeepCopy() *KafkaEndpointSpec { + if in == nil { + return nil + } + out := new(KafkaEndpointSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KerberosConfigFiles) DeepCopyInto(out *KerberosConfigFiles) { + *out = *in + if in.VolumeSource != nil { + in, out := &in.VolumeSource, &out.VolumeSource + *out = new(ConfigFileVolumeSource) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KerberosConfigFiles. +func (in *KerberosConfigFiles) DeepCopy() *KerberosConfigFiles { + if in == nil { + return nil + } + out := new(KerberosConfigFiles) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KerberosKeytabFile) DeepCopyInto(out *KerberosKeytabFile) { + *out = *in + if in.VolumeSource != nil { + in, out := &in.VolumeSource, &out.VolumeSource + *out = new(ConfigFileVolumeSource) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KerberosKeytabFile. +func (in *KerberosKeytabFile) DeepCopy() *KerberosKeytabFile { + if in == nil { + return nil + } + out := new(KerberosKeytabFile) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KerberosSpec) DeepCopyInto(out *KerberosSpec) { + *out = *in + in.ConfigFiles.DeepCopyInto(&out.ConfigFiles) + in.KeytabFile.DeepCopyInto(&out.KeytabFile) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KerberosSpec. +func (in *KerberosSpec) DeepCopy() *KerberosSpec { + if in == nil { + return nil + } + out := new(KerberosSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KeyManagementServiceSpec) DeepCopyInto(out *KeyManagementServiceSpec) { + *out = *in + if in.ConnectionDetails != nil { + in, out := &in.ConnectionDetails, &out.ConnectionDetails + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeyManagementServiceSpec. +func (in *KeyManagementServiceSpec) DeepCopy() *KeyManagementServiceSpec { + if in == nil { + return nil + } + out := new(KeyManagementServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KeyRotationSpec) DeepCopyInto(out *KeyRotationSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeyRotationSpec. +func (in *KeyRotationSpec) DeepCopy() *KeyRotationSpec { + if in == nil { + return nil + } + out := new(KeyRotationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in Labels) DeepCopyInto(out *Labels) { + { + in := &in + *out = make(Labels, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Labels. +func (in Labels) DeepCopy() Labels { + if in == nil { + return nil + } + out := new(Labels) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in LabelsSpec) DeepCopyInto(out *LabelsSpec) { + { + in := &in + *out = make(LabelsSpec, len(*in)) + for key, val := range *in { + var outVal map[string]string + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = make(Labels, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + (*out)[key] = outVal + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LabelsSpec. +func (in LabelsSpec) DeepCopy() LabelsSpec { + if in == nil { + return nil + } + out := new(LabelsSpec) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LogCollectorSpec) DeepCopyInto(out *LogCollectorSpec) { + *out = *in + if in.MaxLogSize != nil { + in, out := &in.MaxLogSize, &out.MaxLogSize + x := (*in).DeepCopy() + *out = &x + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LogCollectorSpec. +func (in *LogCollectorSpec) DeepCopy() *LogCollectorSpec { + if in == nil { + return nil + } + out := new(LogCollectorSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MetadataServerSpec) DeepCopyInto(out *MetadataServerSpec) { + *out = *in + in.Placement.DeepCopyInto(&out.Placement) + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(Annotations, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(Labels, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.Resources.DeepCopyInto(&out.Resources) + if in.LivenessProbe != nil { + in, out := &in.LivenessProbe, &out.LivenessProbe + *out = new(ProbeSpec) + (*in).DeepCopyInto(*out) + } + if in.StartupProbe != nil { + in, out := &in.StartupProbe, &out.StartupProbe + *out = new(ProbeSpec) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetadataServerSpec. +func (in *MetadataServerSpec) DeepCopy() *MetadataServerSpec { + if in == nil { + return nil + } + out := new(MetadataServerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MgrSpec) DeepCopyInto(out *MgrSpec) { + *out = *in + if in.Modules != nil { + in, out := &in.Modules, &out.Modules + *out = make([]Module, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MgrSpec. +func (in *MgrSpec) DeepCopy() *MgrSpec { + if in == nil { + return nil + } + out := new(MgrSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MirrorHealthCheckSpec) DeepCopyInto(out *MirrorHealthCheckSpec) { + *out = *in + in.Mirror.DeepCopyInto(&out.Mirror) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MirrorHealthCheckSpec. +func (in *MirrorHealthCheckSpec) DeepCopy() *MirrorHealthCheckSpec { + if in == nil { + return nil + } + out := new(MirrorHealthCheckSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MirroringInfoSpec) DeepCopyInto(out *MirroringInfoSpec) { + *out = *in + if in.PoolMirroringInfo != nil { + in, out := &in.PoolMirroringInfo, &out.PoolMirroringInfo + *out = new(PoolMirroringInfo) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MirroringInfoSpec. +func (in *MirroringInfoSpec) DeepCopy() *MirroringInfoSpec { + if in == nil { + return nil + } + out := new(MirroringInfoSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MirroringPeerSpec) DeepCopyInto(out *MirroringPeerSpec) { + *out = *in + if in.SecretNames != nil { + in, out := &in.SecretNames, &out.SecretNames + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MirroringPeerSpec. +func (in *MirroringPeerSpec) DeepCopy() *MirroringPeerSpec { + if in == nil { + return nil + } + out := new(MirroringPeerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MirroringSpec) DeepCopyInto(out *MirroringSpec) { + *out = *in + if in.SnapshotSchedules != nil { + in, out := &in.SnapshotSchedules, &out.SnapshotSchedules + *out = make([]SnapshotScheduleSpec, len(*in)) + copy(*out, *in) + } + if in.Peers != nil { + in, out := &in.Peers, &out.Peers + *out = new(MirroringPeerSpec) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MirroringSpec. +func (in *MirroringSpec) DeepCopy() *MirroringSpec { + if in == nil { + return nil + } + out := new(MirroringSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MirroringStatusSpec) DeepCopyInto(out *MirroringStatusSpec) { + *out = *in + in.PoolMirroringStatus.DeepCopyInto(&out.PoolMirroringStatus) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MirroringStatusSpec. +func (in *MirroringStatusSpec) DeepCopy() *MirroringStatusSpec { + if in == nil { + return nil + } + out := new(MirroringStatusSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Module) DeepCopyInto(out *Module) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Module. +func (in *Module) DeepCopy() *Module { + if in == nil { + return nil + } + out := new(Module) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MonSpec) DeepCopyInto(out *MonSpec) { + *out = *in + if in.Zones != nil { + in, out := &in.Zones, &out.Zones + *out = make([]MonZoneSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.StretchCluster != nil { + in, out := &in.StretchCluster, &out.StretchCluster + *out = new(StretchClusterSpec) + (*in).DeepCopyInto(*out) + } + if in.VolumeClaimTemplate != nil { + in, out := &in.VolumeClaimTemplate, &out.VolumeClaimTemplate + *out = new(corev1.PersistentVolumeClaim) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MonSpec. +func (in *MonSpec) DeepCopy() *MonSpec { + if in == nil { + return nil + } + out := new(MonSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MonZoneSpec) DeepCopyInto(out *MonZoneSpec) { + *out = *in + if in.VolumeClaimTemplate != nil { + in, out := &in.VolumeClaimTemplate, &out.VolumeClaimTemplate + *out = new(corev1.PersistentVolumeClaim) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MonZoneSpec. +func (in *MonZoneSpec) DeepCopy() *MonZoneSpec { + if in == nil { + return nil + } + out := new(MonZoneSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MonitoringSpec) DeepCopyInto(out *MonitoringSpec) { + *out = *in + if in.ExternalMgrEndpoints != nil { + in, out := &in.ExternalMgrEndpoints, &out.ExternalMgrEndpoints + *out = make([]corev1.EndpointAddress, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Interval != nil { + in, out := &in.Interval, &out.Interval + *out = new(metav1.Duration) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MonitoringSpec. +func (in *MonitoringSpec) DeepCopy() *MonitoringSpec { + if in == nil { + return nil + } + out := new(MonitoringSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MultiClusterServiceSpec) DeepCopyInto(out *MultiClusterServiceSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultiClusterServiceSpec. +func (in *MultiClusterServiceSpec) DeepCopy() *MultiClusterServiceSpec { + if in == nil { + return nil + } + out := new(MultiClusterServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NFSGaneshaSpec) DeepCopyInto(out *NFSGaneshaSpec) { + *out = *in + out.RADOS = in.RADOS + in.Server.DeepCopyInto(&out.Server) + if in.Security != nil { + in, out := &in.Security, &out.Security + *out = new(NFSSecuritySpec) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NFSGaneshaSpec. +func (in *NFSGaneshaSpec) DeepCopy() *NFSGaneshaSpec { + if in == nil { + return nil + } + out := new(NFSGaneshaSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NFSSecuritySpec) DeepCopyInto(out *NFSSecuritySpec) { + *out = *in + if in.SSSD != nil { + in, out := &in.SSSD, &out.SSSD + *out = new(SSSDSpec) + (*in).DeepCopyInto(*out) + } + if in.Kerberos != nil { + in, out := &in.Kerberos, &out.Kerberos + *out = new(KerberosSpec) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NFSSecuritySpec. +func (in *NFSSecuritySpec) DeepCopy() *NFSSecuritySpec { + if in == nil { + return nil + } + out := new(NFSSecuritySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedBlockPoolSpec) DeepCopyInto(out *NamedBlockPoolSpec) { + *out = *in + in.PoolSpec.DeepCopyInto(&out.PoolSpec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedBlockPoolSpec. +func (in *NamedBlockPoolSpec) DeepCopy() *NamedBlockPoolSpec { + if in == nil { + return nil + } + out := new(NamedBlockPoolSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedPoolSpec) DeepCopyInto(out *NamedPoolSpec) { + *out = *in + in.PoolSpec.DeepCopyInto(&out.PoolSpec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedPoolSpec. +func (in *NamedPoolSpec) DeepCopy() *NamedPoolSpec { + if in == nil { + return nil + } + out := new(NamedPoolSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkSpec) DeepCopyInto(out *NetworkSpec) { + *out = *in + if in.Selectors != nil { + in, out := &in.Selectors, &out.Selectors + *out = make(map[CephNetworkType]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.AddressRanges != nil { + in, out := &in.AddressRanges, &out.AddressRanges + *out = new(AddressRangesSpec) + (*in).DeepCopyInto(*out) + } + if in.Connections != nil { + in, out := &in.Connections, &out.Connections + *out = new(ConnectionsSpec) + (*in).DeepCopyInto(*out) + } + out.MultiClusterService = in.MultiClusterService + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkSpec. +func (in *NetworkSpec) DeepCopy() *NetworkSpec { + if in == nil { + return nil + } + out := new(NetworkSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Node) DeepCopyInto(out *Node) { + *out = *in + in.Resources.DeepCopyInto(&out.Resources) + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.Selection.DeepCopyInto(&out.Selection) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Node. +func (in *Node) DeepCopy() *Node { + if in == nil { + return nil + } + out := new(Node) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in NodesByName) DeepCopyInto(out *NodesByName) { + { + in := &in + *out = make(NodesByName, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodesByName. +func (in NodesByName) DeepCopy() NodesByName { + if in == nil { + return nil + } + out := new(NodesByName) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NotificationFilterRule) DeepCopyInto(out *NotificationFilterRule) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NotificationFilterRule. +func (in *NotificationFilterRule) DeepCopy() *NotificationFilterRule { + if in == nil { + return nil + } + out := new(NotificationFilterRule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NotificationFilterSpec) DeepCopyInto(out *NotificationFilterSpec) { + *out = *in + if in.KeyFilters != nil { + in, out := &in.KeyFilters, &out.KeyFilters + *out = make([]NotificationKeyFilterRule, len(*in)) + copy(*out, *in) + } + if in.MetadataFilters != nil { + in, out := &in.MetadataFilters, &out.MetadataFilters + *out = make([]NotificationFilterRule, len(*in)) + copy(*out, *in) + } + if in.TagFilters != nil { + in, out := &in.TagFilters, &out.TagFilters + *out = make([]NotificationFilterRule, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NotificationFilterSpec. +func (in *NotificationFilterSpec) DeepCopy() *NotificationFilterSpec { + if in == nil { + return nil + } + out := new(NotificationFilterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NotificationKeyFilterRule) DeepCopyInto(out *NotificationKeyFilterRule) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NotificationKeyFilterRule. +func (in *NotificationKeyFilterRule) DeepCopy() *NotificationKeyFilterRule { + if in == nil { + return nil + } + out := new(NotificationKeyFilterRule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OSDStatus) DeepCopyInto(out *OSDStatus) { + *out = *in + if in.StoreType != nil { + in, out := &in.StoreType, &out.StoreType + *out = make(map[string]int, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSDStatus. +func (in *OSDStatus) DeepCopy() *OSDStatus { + if in == nil { + return nil + } + out := new(OSDStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OSDStore) DeepCopyInto(out *OSDStore) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSDStore. +func (in *OSDStore) DeepCopy() *OSDStore { + if in == nil { + return nil + } + out := new(OSDStore) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectEndpoints) DeepCopyInto(out *ObjectEndpoints) { + *out = *in + if in.Insecure != nil { + in, out := &in.Insecure, &out.Insecure + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Secure != nil { + in, out := &in.Secure, &out.Secure + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectEndpoints. +func (in *ObjectEndpoints) DeepCopy() *ObjectEndpoints { + if in == nil { + return nil + } + out := new(ObjectEndpoints) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectHealthCheckSpec) DeepCopyInto(out *ObjectHealthCheckSpec) { + *out = *in + if in.ReadinessProbe != nil { + in, out := &in.ReadinessProbe, &out.ReadinessProbe + *out = new(ProbeSpec) + (*in).DeepCopyInto(*out) + } + if in.StartupProbe != nil { + in, out := &in.StartupProbe, &out.StartupProbe + *out = new(ProbeSpec) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectHealthCheckSpec. +func (in *ObjectHealthCheckSpec) DeepCopy() *ObjectHealthCheckSpec { + if in == nil { + return nil + } + out := new(ObjectHealthCheckSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectRealmSpec) DeepCopyInto(out *ObjectRealmSpec) { + *out = *in + out.Pull = in.Pull + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectRealmSpec. +func (in *ObjectRealmSpec) DeepCopy() *ObjectRealmSpec { + if in == nil { + return nil + } + out := new(ObjectRealmSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectStoreSecuritySpec) DeepCopyInto(out *ObjectStoreSecuritySpec) { + *out = *in + in.SecuritySpec.DeepCopyInto(&out.SecuritySpec) + in.ServerSideEncryptionS3.DeepCopyInto(&out.ServerSideEncryptionS3) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectStoreSecuritySpec. +func (in *ObjectStoreSecuritySpec) DeepCopy() *ObjectStoreSecuritySpec { + if in == nil { + return nil + } + out := new(ObjectStoreSecuritySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectStoreSpec) DeepCopyInto(out *ObjectStoreSpec) { + *out = *in + in.MetadataPool.DeepCopyInto(&out.MetadataPool) + in.DataPool.DeepCopyInto(&out.DataPool) + in.Gateway.DeepCopyInto(&out.Gateway) + out.Zone = in.Zone + in.HealthCheck.DeepCopyInto(&out.HealthCheck) + if in.Security != nil { + in, out := &in.Security, &out.Security + *out = new(ObjectStoreSecuritySpec) + (*in).DeepCopyInto(*out) + } + if in.AllowUsersInNamespaces != nil { + in, out := &in.AllowUsersInNamespaces, &out.AllowUsersInNamespaces + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectStoreSpec. +func (in *ObjectStoreSpec) DeepCopy() *ObjectStoreSpec { + if in == nil { + return nil + } + out := new(ObjectStoreSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectStoreStatus) DeepCopyInto(out *ObjectStoreStatus) { + *out = *in + in.Endpoints.DeepCopyInto(&out.Endpoints) + if in.Info != nil { + in, out := &in.Info, &out.Info + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectStoreStatus. +func (in *ObjectStoreStatus) DeepCopy() *ObjectStoreStatus { + if in == nil { + return nil + } + out := new(ObjectStoreStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectStoreUserSpec) DeepCopyInto(out *ObjectStoreUserSpec) { + *out = *in + if in.Capabilities != nil { + in, out := &in.Capabilities, &out.Capabilities + *out = new(ObjectUserCapSpec) + **out = **in + } + if in.Quotas != nil { + in, out := &in.Quotas, &out.Quotas + *out = new(ObjectUserQuotaSpec) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectStoreUserSpec. +func (in *ObjectStoreUserSpec) DeepCopy() *ObjectStoreUserSpec { + if in == nil { + return nil + } + out := new(ObjectStoreUserSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectStoreUserStatus) DeepCopyInto(out *ObjectStoreUserStatus) { + *out = *in + if in.Info != nil { + in, out := &in.Info, &out.Info + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectStoreUserStatus. +func (in *ObjectStoreUserStatus) DeepCopy() *ObjectStoreUserStatus { + if in == nil { + return nil + } + out := new(ObjectStoreUserStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectUserCapSpec) DeepCopyInto(out *ObjectUserCapSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectUserCapSpec. +func (in *ObjectUserCapSpec) DeepCopy() *ObjectUserCapSpec { + if in == nil { + return nil + } + out := new(ObjectUserCapSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectUserQuotaSpec) DeepCopyInto(out *ObjectUserQuotaSpec) { + *out = *in + if in.MaxBuckets != nil { + in, out := &in.MaxBuckets, &out.MaxBuckets + *out = new(int) + **out = **in + } + if in.MaxSize != nil { + in, out := &in.MaxSize, &out.MaxSize + x := (*in).DeepCopy() + *out = &x + } + if in.MaxObjects != nil { + in, out := &in.MaxObjects, &out.MaxObjects + *out = new(int64) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectUserQuotaSpec. +func (in *ObjectUserQuotaSpec) DeepCopy() *ObjectUserQuotaSpec { + if in == nil { + return nil + } + out := new(ObjectUserQuotaSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectZoneGroupSpec) DeepCopyInto(out *ObjectZoneGroupSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectZoneGroupSpec. +func (in *ObjectZoneGroupSpec) DeepCopy() *ObjectZoneGroupSpec { + if in == nil { + return nil + } + out := new(ObjectZoneGroupSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectZoneSpec) DeepCopyInto(out *ObjectZoneSpec) { + *out = *in + in.MetadataPool.DeepCopyInto(&out.MetadataPool) + in.DataPool.DeepCopyInto(&out.DataPool) + if in.CustomEndpoints != nil { + in, out := &in.CustomEndpoints, &out.CustomEndpoints + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectZoneSpec. +func (in *ObjectZoneSpec) DeepCopy() *ObjectZoneSpec { + if in == nil { + return nil + } + out := new(ObjectZoneSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PeerRemoteSpec) DeepCopyInto(out *PeerRemoteSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PeerRemoteSpec. +func (in *PeerRemoteSpec) DeepCopy() *PeerRemoteSpec { + if in == nil { + return nil + } + out := new(PeerRemoteSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PeerStatSpec) DeepCopyInto(out *PeerStatSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PeerStatSpec. +func (in *PeerStatSpec) DeepCopy() *PeerStatSpec { + if in == nil { + return nil + } + out := new(PeerStatSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PeersSpec) DeepCopyInto(out *PeersSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PeersSpec. +func (in *PeersSpec) DeepCopy() *PeersSpec { + if in == nil { + return nil + } + out := new(PeersSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Placement) DeepCopyInto(out *Placement) { + *out = *in + if in.NodeAffinity != nil { + in, out := &in.NodeAffinity, &out.NodeAffinity + *out = new(corev1.NodeAffinity) + (*in).DeepCopyInto(*out) + } + if in.PodAffinity != nil { + in, out := &in.PodAffinity, &out.PodAffinity + *out = new(corev1.PodAffinity) + (*in).DeepCopyInto(*out) + } + if in.PodAntiAffinity != nil { + in, out := &in.PodAntiAffinity, &out.PodAntiAffinity + *out = new(corev1.PodAntiAffinity) + (*in).DeepCopyInto(*out) + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]corev1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.TopologySpreadConstraints != nil { + in, out := &in.TopologySpreadConstraints, &out.TopologySpreadConstraints + *out = make([]corev1.TopologySpreadConstraint, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Placement. +func (in *Placement) DeepCopy() *Placement { + if in == nil { + return nil + } + out := new(Placement) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in PlacementSpec) DeepCopyInto(out *PlacementSpec) { + { + in := &in + *out = make(PlacementSpec, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PlacementSpec. +func (in PlacementSpec) DeepCopy() PlacementSpec { + if in == nil { + return nil + } + out := new(PlacementSpec) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PoolMirroringInfo) DeepCopyInto(out *PoolMirroringInfo) { + *out = *in + if in.Peers != nil { + in, out := &in.Peers, &out.Peers + *out = make([]PeersSpec, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PoolMirroringInfo. +func (in *PoolMirroringInfo) DeepCopy() *PoolMirroringInfo { + if in == nil { + return nil + } + out := new(PoolMirroringInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PoolMirroringStatus) DeepCopyInto(out *PoolMirroringStatus) { + *out = *in + if in.Summary != nil { + in, out := &in.Summary, &out.Summary + *out = new(PoolMirroringStatusSummarySpec) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PoolMirroringStatus. +func (in *PoolMirroringStatus) DeepCopy() *PoolMirroringStatus { + if in == nil { + return nil + } + out := new(PoolMirroringStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PoolMirroringStatusSummarySpec) DeepCopyInto(out *PoolMirroringStatusSummarySpec) { + *out = *in + out.States = in.States + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PoolMirroringStatusSummarySpec. +func (in *PoolMirroringStatusSummarySpec) DeepCopy() *PoolMirroringStatusSummarySpec { + if in == nil { + return nil + } + out := new(PoolMirroringStatusSummarySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PoolSpec) DeepCopyInto(out *PoolSpec) { + *out = *in + in.Replicated.DeepCopyInto(&out.Replicated) + out.ErasureCoded = in.ErasureCoded + if in.Parameters != nil { + in, out := &in.Parameters, &out.Parameters + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.Mirroring.DeepCopyInto(&out.Mirroring) + in.StatusCheck.DeepCopyInto(&out.StatusCheck) + in.Quotas.DeepCopyInto(&out.Quotas) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PoolSpec. +func (in *PoolSpec) DeepCopy() *PoolSpec { + if in == nil { + return nil + } + out := new(PoolSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in PriorityClassNamesSpec) DeepCopyInto(out *PriorityClassNamesSpec) { + { + in := &in + *out = make(PriorityClassNamesSpec, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PriorityClassNamesSpec. +func (in PriorityClassNamesSpec) DeepCopy() PriorityClassNamesSpec { + if in == nil { + return nil + } + out := new(PriorityClassNamesSpec) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProbeSpec) DeepCopyInto(out *ProbeSpec) { + *out = *in + if in.Probe != nil { + in, out := &in.Probe, &out.Probe + *out = new(corev1.Probe) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProbeSpec. +func (in *ProbeSpec) DeepCopy() *ProbeSpec { + if in == nil { + return nil + } + out := new(ProbeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PullSpec) DeepCopyInto(out *PullSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PullSpec. +func (in *PullSpec) DeepCopy() *PullSpec { + if in == nil { + return nil + } + out := new(PullSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *QuotaSpec) DeepCopyInto(out *QuotaSpec) { + *out = *in + if in.MaxBytes != nil { + in, out := &in.MaxBytes, &out.MaxBytes + *out = new(uint64) + **out = **in + } + if in.MaxSize != nil { + in, out := &in.MaxSize, &out.MaxSize + *out = new(string) + **out = **in + } + if in.MaxObjects != nil { + in, out := &in.MaxObjects, &out.MaxObjects + *out = new(uint64) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new QuotaSpec. +func (in *QuotaSpec) DeepCopy() *QuotaSpec { + if in == nil { + return nil + } + out := new(QuotaSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RBDMirroringSpec) DeepCopyInto(out *RBDMirroringSpec) { + *out = *in + in.Peers.DeepCopyInto(&out.Peers) + in.Placement.DeepCopyInto(&out.Placement) + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(Annotations, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(Labels, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.Resources.DeepCopyInto(&out.Resources) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RBDMirroringSpec. +func (in *RBDMirroringSpec) DeepCopy() *RBDMirroringSpec { + if in == nil { + return nil + } + out := new(RBDMirroringSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RGWServiceSpec) DeepCopyInto(out *RGWServiceSpec) { + *out = *in + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(Annotations, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RGWServiceSpec. +func (in *RGWServiceSpec) DeepCopy() *RGWServiceSpec { + if in == nil { + return nil + } + out := new(RGWServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReadAffinitySpec) DeepCopyInto(out *ReadAffinitySpec) { + *out = *in + if in.CrushLocationLabels != nil { + in, out := &in.CrushLocationLabels, &out.CrushLocationLabels + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReadAffinitySpec. +func (in *ReadAffinitySpec) DeepCopy() *ReadAffinitySpec { + if in == nil { + return nil + } + out := new(ReadAffinitySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReplicatedSpec) DeepCopyInto(out *ReplicatedSpec) { + *out = *in + if in.HybridStorage != nil { + in, out := &in.HybridStorage, &out.HybridStorage + *out = new(HybridStorageSpec) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicatedSpec. +func (in *ReplicatedSpec) DeepCopy() *ReplicatedSpec { + if in == nil { + return nil + } + out := new(ReplicatedSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in ResourceSpec) DeepCopyInto(out *ResourceSpec) { + { + in := &in + *out = make(ResourceSpec, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceSpec. +func (in ResourceSpec) DeepCopy() ResourceSpec { + if in == nil { + return nil + } + out := new(ResourceSpec) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SSSDSidecar) DeepCopyInto(out *SSSDSidecar) { + *out = *in + in.SSSDConfigFile.DeepCopyInto(&out.SSSDConfigFile) + if in.AdditionalFiles != nil { + in, out := &in.AdditionalFiles, &out.AdditionalFiles + *out = make([]SSSDSidecarAdditionalFile, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Resources.DeepCopyInto(&out.Resources) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSSDSidecar. +func (in *SSSDSidecar) DeepCopy() *SSSDSidecar { + if in == nil { + return nil + } + out := new(SSSDSidecar) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SSSDSidecarAdditionalFile) DeepCopyInto(out *SSSDSidecarAdditionalFile) { + *out = *in + if in.VolumeSource != nil { + in, out := &in.VolumeSource, &out.VolumeSource + *out = new(ConfigFileVolumeSource) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSSDSidecarAdditionalFile. +func (in *SSSDSidecarAdditionalFile) DeepCopy() *SSSDSidecarAdditionalFile { + if in == nil { + return nil + } + out := new(SSSDSidecarAdditionalFile) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SSSDSidecarConfigFile) DeepCopyInto(out *SSSDSidecarConfigFile) { + *out = *in + if in.VolumeSource != nil { + in, out := &in.VolumeSource, &out.VolumeSource + *out = new(ConfigFileVolumeSource) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSSDSidecarConfigFile. +func (in *SSSDSidecarConfigFile) DeepCopy() *SSSDSidecarConfigFile { + if in == nil { + return nil + } + out := new(SSSDSidecarConfigFile) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SSSDSpec) DeepCopyInto(out *SSSDSpec) { + *out = *in + if in.Sidecar != nil { + in, out := &in.Sidecar, &out.Sidecar + *out = new(SSSDSidecar) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSSDSpec. +func (in *SSSDSpec) DeepCopy() *SSSDSpec { + if in == nil { + return nil + } + out := new(SSSDSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SanitizeDisksSpec) DeepCopyInto(out *SanitizeDisksSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SanitizeDisksSpec. +func (in *SanitizeDisksSpec) DeepCopy() *SanitizeDisksSpec { + if in == nil { + return nil + } + out := new(SanitizeDisksSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecuritySpec) DeepCopyInto(out *SecuritySpec) { + *out = *in + in.KeyManagementService.DeepCopyInto(&out.KeyManagementService) + out.KeyRotation = in.KeyRotation + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecuritySpec. +func (in *SecuritySpec) DeepCopy() *SecuritySpec { + if in == nil { + return nil + } + out := new(SecuritySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Selection) DeepCopyInto(out *Selection) { + *out = *in + if in.UseAllDevices != nil { + in, out := &in.UseAllDevices, &out.UseAllDevices + *out = new(bool) + **out = **in + } + if in.Devices != nil { + in, out := &in.Devices, &out.Devices + *out = make([]Device, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.VolumeClaimTemplates != nil { + in, out := &in.VolumeClaimTemplates, &out.VolumeClaimTemplates + *out = make([]corev1.PersistentVolumeClaim, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Selection. +func (in *Selection) DeepCopy() *Selection { + if in == nil { + return nil + } + out := new(Selection) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SnapshotSchedule) DeepCopyInto(out *SnapshotSchedule) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SnapshotSchedule. +func (in *SnapshotSchedule) DeepCopy() *SnapshotSchedule { + if in == nil { + return nil + } + out := new(SnapshotSchedule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SnapshotScheduleRetentionSpec) DeepCopyInto(out *SnapshotScheduleRetentionSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SnapshotScheduleRetentionSpec. +func (in *SnapshotScheduleRetentionSpec) DeepCopy() *SnapshotScheduleRetentionSpec { + if in == nil { + return nil + } + out := new(SnapshotScheduleRetentionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SnapshotScheduleSpec) DeepCopyInto(out *SnapshotScheduleSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SnapshotScheduleSpec. +func (in *SnapshotScheduleSpec) DeepCopy() *SnapshotScheduleSpec { + if in == nil { + return nil + } + out := new(SnapshotScheduleSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SnapshotScheduleStatusSpec) DeepCopyInto(out *SnapshotScheduleStatusSpec) { + *out = *in + if in.SnapshotSchedules != nil { + in, out := &in.SnapshotSchedules, &out.SnapshotSchedules + *out = make([]SnapshotSchedulesSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SnapshotScheduleStatusSpec. +func (in *SnapshotScheduleStatusSpec) DeepCopy() *SnapshotScheduleStatusSpec { + if in == nil { + return nil + } + out := new(SnapshotScheduleStatusSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SnapshotSchedulesSpec) DeepCopyInto(out *SnapshotSchedulesSpec) { + *out = *in + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]SnapshotSchedule, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SnapshotSchedulesSpec. +func (in *SnapshotSchedulesSpec) DeepCopy() *SnapshotSchedulesSpec { + if in == nil { + return nil + } + out := new(SnapshotSchedulesSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StatesSpec) DeepCopyInto(out *StatesSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatesSpec. +func (in *StatesSpec) DeepCopy() *StatesSpec { + if in == nil { + return nil + } + out := new(StatesSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Status) DeepCopyInto(out *Status) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Status. +func (in *Status) DeepCopy() *Status { + if in == nil { + return nil + } + out := new(Status) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StorageClassDeviceSet) DeepCopyInto(out *StorageClassDeviceSet) { + *out = *in + in.Resources.DeepCopyInto(&out.Resources) + in.Placement.DeepCopyInto(&out.Placement) + if in.PreparePlacement != nil { + in, out := &in.PreparePlacement, &out.PreparePlacement + *out = new(Placement) + (*in).DeepCopyInto(*out) + } + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.VolumeClaimTemplates != nil { + in, out := &in.VolumeClaimTemplates, &out.VolumeClaimTemplates + *out = make([]corev1.PersistentVolumeClaim, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageClassDeviceSet. +func (in *StorageClassDeviceSet) DeepCopy() *StorageClassDeviceSet { + if in == nil { + return nil + } + out := new(StorageClassDeviceSet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StorageScopeSpec) DeepCopyInto(out *StorageScopeSpec) { + *out = *in + if in.Nodes != nil { + in, out := &in.Nodes, &out.Nodes + *out = make([]Node, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.Selection.DeepCopyInto(&out.Selection) + if in.StorageClassDeviceSets != nil { + in, out := &in.StorageClassDeviceSets, &out.StorageClassDeviceSets + *out = make([]StorageClassDeviceSet, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + out.Store = in.Store + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageScopeSpec. +func (in *StorageScopeSpec) DeepCopy() *StorageScopeSpec { + if in == nil { + return nil + } + out := new(StorageScopeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StretchClusterSpec) DeepCopyInto(out *StretchClusterSpec) { + *out = *in + if in.Zones != nil { + in, out := &in.Zones, &out.Zones + *out = make([]MonZoneSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StretchClusterSpec. +func (in *StretchClusterSpec) DeepCopy() *StretchClusterSpec { + if in == nil { + return nil + } + out := new(StretchClusterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TopicEndpointSpec) DeepCopyInto(out *TopicEndpointSpec) { + *out = *in + if in.HTTP != nil { + in, out := &in.HTTP, &out.HTTP + *out = new(HTTPEndpointSpec) + **out = **in + } + if in.AMQP != nil { + in, out := &in.AMQP, &out.AMQP + *out = new(AMQPEndpointSpec) + **out = **in + } + if in.Kafka != nil { + in, out := &in.Kafka, &out.Kafka + *out = new(KafkaEndpointSpec) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TopicEndpointSpec. +func (in *TopicEndpointSpec) DeepCopy() *TopicEndpointSpec { + if in == nil { + return nil + } + out := new(TopicEndpointSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ZoneSpec) DeepCopyInto(out *ZoneSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ZoneSpec. +func (in *ZoneSpec) DeepCopy() *ZoneSpec { + if in == nil { + return nil + } + out := new(ZoneSpec) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/clientset.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/clientset.go new file mode 100644 index 00000000000..64225957621 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/clientset.go @@ -0,0 +1,97 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package versioned + +import ( + "fmt" + + cephv1 "github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1" + discovery "k8s.io/client-go/discovery" + rest "k8s.io/client-go/rest" + flowcontrol "k8s.io/client-go/util/flowcontrol" +) + +type Interface interface { + Discovery() discovery.DiscoveryInterface + CephV1() cephv1.CephV1Interface +} + +// Clientset contains the clients for groups. Each group has exactly one +// version included in a Clientset. +type Clientset struct { + *discovery.DiscoveryClient + cephV1 *cephv1.CephV1Client +} + +// CephV1 retrieves the CephV1Client +func (c *Clientset) CephV1() cephv1.CephV1Interface { + return c.cephV1 +} + +// Discovery retrieves the DiscoveryClient +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + if c == nil { + return nil + } + return c.DiscoveryClient +} + +// NewForConfig creates a new Clientset for the given config. +// If config's RateLimiter is not set and QPS and Burst are acceptable, +// NewForConfig will generate a rate-limiter in configShallowCopy. +func NewForConfig(c *rest.Config) (*Clientset, error) { + configShallowCopy := *c + if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { + if configShallowCopy.Burst <= 0 { + return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0") + } + configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) + } + var cs Clientset + var err error + cs.cephV1, err = cephv1.NewForConfig(&configShallowCopy) + if err != nil { + return nil, err + } + + cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) + if err != nil { + return nil, err + } + return &cs, nil +} + +// NewForConfigOrDie creates a new Clientset for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *Clientset { + var cs Clientset + cs.cephV1 = cephv1.NewForConfigOrDie(c) + + cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) + return &cs +} + +// New creates a new Clientset for the given RESTClient. +func New(c rest.Interface) *Clientset { + var cs Clientset + cs.cephV1 = cephv1.New(c) + + cs.DiscoveryClient = discovery.NewDiscoveryClient(c) + return &cs +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/doc.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/doc.go new file mode 100644 index 00000000000..41721ca52d4 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated clientset. +package versioned diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/scheme/doc.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/scheme/doc.go new file mode 100644 index 00000000000..7dc3756168f --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/scheme/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package contains the scheme of the automatically generated clientset. +package scheme diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/scheme/register.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/scheme/register.go new file mode 100644 index 00000000000..8f2fcea75d2 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/scheme/register.go @@ -0,0 +1,56 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package scheme + +import ( + cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +var Scheme = runtime.NewScheme() +var Codecs = serializer.NewCodecFactory(Scheme) +var ParameterCodec = runtime.NewParameterCodec(Scheme) +var localSchemeBuilder = runtime.SchemeBuilder{ + cephv1.AddToScheme, +} + +// AddToScheme adds all types of this clientset into the given scheme. This allows composition +// of clientsets, like in: +// +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) +// +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// +// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types +// correctly. +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(Scheme)) +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/ceph.rook.io_client.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/ceph.rook.io_client.go new file mode 100644 index 00000000000..59f25fd0dd0 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/ceph.rook.io_client.go @@ -0,0 +1,169 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" +) + +type CephV1Interface interface { + RESTClient() rest.Interface + CephBlockPoolsGetter + CephBlockPoolRadosNamespacesGetter + CephBucketNotificationsGetter + CephBucketTopicsGetter + CephCOSIDriversGetter + CephClientsGetter + CephClustersGetter + CephFilesystemsGetter + CephFilesystemMirrorsGetter + CephFilesystemSubVolumeGroupsGetter + CephNFSesGetter + CephObjectRealmsGetter + CephObjectStoresGetter + CephObjectStoreUsersGetter + CephObjectZonesGetter + CephObjectZoneGroupsGetter + CephRBDMirrorsGetter +} + +// CephV1Client is used to interact with features provided by the ceph.rook.io group. +type CephV1Client struct { + restClient rest.Interface +} + +func (c *CephV1Client) CephBlockPools(namespace string) CephBlockPoolInterface { + return newCephBlockPools(c, namespace) +} + +func (c *CephV1Client) CephBlockPoolRadosNamespaces(namespace string) CephBlockPoolRadosNamespaceInterface { + return newCephBlockPoolRadosNamespaces(c, namespace) +} + +func (c *CephV1Client) CephBucketNotifications(namespace string) CephBucketNotificationInterface { + return newCephBucketNotifications(c, namespace) +} + +func (c *CephV1Client) CephBucketTopics(namespace string) CephBucketTopicInterface { + return newCephBucketTopics(c, namespace) +} + +func (c *CephV1Client) CephCOSIDrivers(namespace string) CephCOSIDriverInterface { + return newCephCOSIDrivers(c, namespace) +} + +func (c *CephV1Client) CephClients(namespace string) CephClientInterface { + return newCephClients(c, namespace) +} + +func (c *CephV1Client) CephClusters(namespace string) CephClusterInterface { + return newCephClusters(c, namespace) +} + +func (c *CephV1Client) CephFilesystems(namespace string) CephFilesystemInterface { + return newCephFilesystems(c, namespace) +} + +func (c *CephV1Client) CephFilesystemMirrors(namespace string) CephFilesystemMirrorInterface { + return newCephFilesystemMirrors(c, namespace) +} + +func (c *CephV1Client) CephFilesystemSubVolumeGroups(namespace string) CephFilesystemSubVolumeGroupInterface { + return newCephFilesystemSubVolumeGroups(c, namespace) +} + +func (c *CephV1Client) CephNFSes(namespace string) CephNFSInterface { + return newCephNFSes(c, namespace) +} + +func (c *CephV1Client) CephObjectRealms(namespace string) CephObjectRealmInterface { + return newCephObjectRealms(c, namespace) +} + +func (c *CephV1Client) CephObjectStores(namespace string) CephObjectStoreInterface { + return newCephObjectStores(c, namespace) +} + +func (c *CephV1Client) CephObjectStoreUsers(namespace string) CephObjectStoreUserInterface { + return newCephObjectStoreUsers(c, namespace) +} + +func (c *CephV1Client) CephObjectZones(namespace string) CephObjectZoneInterface { + return newCephObjectZones(c, namespace) +} + +func (c *CephV1Client) CephObjectZoneGroups(namespace string) CephObjectZoneGroupInterface { + return newCephObjectZoneGroups(c, namespace) +} + +func (c *CephV1Client) CephRBDMirrors(namespace string) CephRBDMirrorInterface { + return newCephRBDMirrors(c, namespace) +} + +// NewForConfig creates a new CephV1Client for the given config. +func NewForConfig(c *rest.Config) (*CephV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &CephV1Client{client}, nil +} + +// NewForConfigOrDie creates a new CephV1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *CephV1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new CephV1Client for the given RESTClient. +func New(c rest.Interface) *CephV1Client { + return &CephV1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *CephV1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephblockpool.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephblockpool.go new file mode 100644 index 00000000000..b222f65fdc6 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephblockpool.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephBlockPoolsGetter has a method to return a CephBlockPoolInterface. +// A group's client should implement this interface. +type CephBlockPoolsGetter interface { + CephBlockPools(namespace string) CephBlockPoolInterface +} + +// CephBlockPoolInterface has methods to work with CephBlockPool resources. +type CephBlockPoolInterface interface { + Create(ctx context.Context, cephBlockPool *v1.CephBlockPool, opts metav1.CreateOptions) (*v1.CephBlockPool, error) + Update(ctx context.Context, cephBlockPool *v1.CephBlockPool, opts metav1.UpdateOptions) (*v1.CephBlockPool, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephBlockPool, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephBlockPoolList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephBlockPool, err error) + CephBlockPoolExpansion +} + +// cephBlockPools implements CephBlockPoolInterface +type cephBlockPools struct { + client rest.Interface + ns string +} + +// newCephBlockPools returns a CephBlockPools +func newCephBlockPools(c *CephV1Client, namespace string) *cephBlockPools { + return &cephBlockPools{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephBlockPool, and returns the corresponding cephBlockPool object, and an error if there is any. +func (c *cephBlockPools) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephBlockPool, err error) { + result = &v1.CephBlockPool{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephblockpools"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephBlockPools that match those selectors. +func (c *cephBlockPools) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephBlockPoolList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephBlockPoolList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephblockpools"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephBlockPools. +func (c *cephBlockPools) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephblockpools"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephBlockPool and creates it. Returns the server's representation of the cephBlockPool, and an error, if there is any. +func (c *cephBlockPools) Create(ctx context.Context, cephBlockPool *v1.CephBlockPool, opts metav1.CreateOptions) (result *v1.CephBlockPool, err error) { + result = &v1.CephBlockPool{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephblockpools"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephBlockPool). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephBlockPool and updates it. Returns the server's representation of the cephBlockPool, and an error, if there is any. +func (c *cephBlockPools) Update(ctx context.Context, cephBlockPool *v1.CephBlockPool, opts metav1.UpdateOptions) (result *v1.CephBlockPool, err error) { + result = &v1.CephBlockPool{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephblockpools"). + Name(cephBlockPool.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephBlockPool). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephBlockPool and deletes it. Returns an error if one occurs. +func (c *cephBlockPools) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephblockpools"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephBlockPools) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephblockpools"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephBlockPool. +func (c *cephBlockPools) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephBlockPool, err error) { + result = &v1.CephBlockPool{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephblockpools"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephblockpoolradosnamespace.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephblockpoolradosnamespace.go new file mode 100644 index 00000000000..0883cb40bf1 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephblockpoolradosnamespace.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephBlockPoolRadosNamespacesGetter has a method to return a CephBlockPoolRadosNamespaceInterface. +// A group's client should implement this interface. +type CephBlockPoolRadosNamespacesGetter interface { + CephBlockPoolRadosNamespaces(namespace string) CephBlockPoolRadosNamespaceInterface +} + +// CephBlockPoolRadosNamespaceInterface has methods to work with CephBlockPoolRadosNamespace resources. +type CephBlockPoolRadosNamespaceInterface interface { + Create(ctx context.Context, cephBlockPoolRadosNamespace *v1.CephBlockPoolRadosNamespace, opts metav1.CreateOptions) (*v1.CephBlockPoolRadosNamespace, error) + Update(ctx context.Context, cephBlockPoolRadosNamespace *v1.CephBlockPoolRadosNamespace, opts metav1.UpdateOptions) (*v1.CephBlockPoolRadosNamespace, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephBlockPoolRadosNamespace, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephBlockPoolRadosNamespaceList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephBlockPoolRadosNamespace, err error) + CephBlockPoolRadosNamespaceExpansion +} + +// cephBlockPoolRadosNamespaces implements CephBlockPoolRadosNamespaceInterface +type cephBlockPoolRadosNamespaces struct { + client rest.Interface + ns string +} + +// newCephBlockPoolRadosNamespaces returns a CephBlockPoolRadosNamespaces +func newCephBlockPoolRadosNamespaces(c *CephV1Client, namespace string) *cephBlockPoolRadosNamespaces { + return &cephBlockPoolRadosNamespaces{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephBlockPoolRadosNamespace, and returns the corresponding cephBlockPoolRadosNamespace object, and an error if there is any. +func (c *cephBlockPoolRadosNamespaces) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephBlockPoolRadosNamespace, err error) { + result = &v1.CephBlockPoolRadosNamespace{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephblockpoolradosnamespaces"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephBlockPoolRadosNamespaces that match those selectors. +func (c *cephBlockPoolRadosNamespaces) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephBlockPoolRadosNamespaceList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephBlockPoolRadosNamespaceList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephblockpoolradosnamespaces"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephBlockPoolRadosNamespaces. +func (c *cephBlockPoolRadosNamespaces) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephblockpoolradosnamespaces"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephBlockPoolRadosNamespace and creates it. Returns the server's representation of the cephBlockPoolRadosNamespace, and an error, if there is any. +func (c *cephBlockPoolRadosNamespaces) Create(ctx context.Context, cephBlockPoolRadosNamespace *v1.CephBlockPoolRadosNamespace, opts metav1.CreateOptions) (result *v1.CephBlockPoolRadosNamespace, err error) { + result = &v1.CephBlockPoolRadosNamespace{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephblockpoolradosnamespaces"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephBlockPoolRadosNamespace). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephBlockPoolRadosNamespace and updates it. Returns the server's representation of the cephBlockPoolRadosNamespace, and an error, if there is any. +func (c *cephBlockPoolRadosNamespaces) Update(ctx context.Context, cephBlockPoolRadosNamespace *v1.CephBlockPoolRadosNamespace, opts metav1.UpdateOptions) (result *v1.CephBlockPoolRadosNamespace, err error) { + result = &v1.CephBlockPoolRadosNamespace{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephblockpoolradosnamespaces"). + Name(cephBlockPoolRadosNamespace.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephBlockPoolRadosNamespace). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephBlockPoolRadosNamespace and deletes it. Returns an error if one occurs. +func (c *cephBlockPoolRadosNamespaces) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephblockpoolradosnamespaces"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephBlockPoolRadosNamespaces) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephblockpoolradosnamespaces"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephBlockPoolRadosNamespace. +func (c *cephBlockPoolRadosNamespaces) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephBlockPoolRadosNamespace, err error) { + result = &v1.CephBlockPoolRadosNamespace{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephblockpoolradosnamespaces"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephbucketnotification.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephbucketnotification.go new file mode 100644 index 00000000000..37e9dd77ee7 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephbucketnotification.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephBucketNotificationsGetter has a method to return a CephBucketNotificationInterface. +// A group's client should implement this interface. +type CephBucketNotificationsGetter interface { + CephBucketNotifications(namespace string) CephBucketNotificationInterface +} + +// CephBucketNotificationInterface has methods to work with CephBucketNotification resources. +type CephBucketNotificationInterface interface { + Create(ctx context.Context, cephBucketNotification *v1.CephBucketNotification, opts metav1.CreateOptions) (*v1.CephBucketNotification, error) + Update(ctx context.Context, cephBucketNotification *v1.CephBucketNotification, opts metav1.UpdateOptions) (*v1.CephBucketNotification, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephBucketNotification, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephBucketNotificationList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephBucketNotification, err error) + CephBucketNotificationExpansion +} + +// cephBucketNotifications implements CephBucketNotificationInterface +type cephBucketNotifications struct { + client rest.Interface + ns string +} + +// newCephBucketNotifications returns a CephBucketNotifications +func newCephBucketNotifications(c *CephV1Client, namespace string) *cephBucketNotifications { + return &cephBucketNotifications{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephBucketNotification, and returns the corresponding cephBucketNotification object, and an error if there is any. +func (c *cephBucketNotifications) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephBucketNotification, err error) { + result = &v1.CephBucketNotification{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephbucketnotifications"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephBucketNotifications that match those selectors. +func (c *cephBucketNotifications) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephBucketNotificationList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephBucketNotificationList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephbucketnotifications"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephBucketNotifications. +func (c *cephBucketNotifications) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephbucketnotifications"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephBucketNotification and creates it. Returns the server's representation of the cephBucketNotification, and an error, if there is any. +func (c *cephBucketNotifications) Create(ctx context.Context, cephBucketNotification *v1.CephBucketNotification, opts metav1.CreateOptions) (result *v1.CephBucketNotification, err error) { + result = &v1.CephBucketNotification{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephbucketnotifications"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephBucketNotification). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephBucketNotification and updates it. Returns the server's representation of the cephBucketNotification, and an error, if there is any. +func (c *cephBucketNotifications) Update(ctx context.Context, cephBucketNotification *v1.CephBucketNotification, opts metav1.UpdateOptions) (result *v1.CephBucketNotification, err error) { + result = &v1.CephBucketNotification{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephbucketnotifications"). + Name(cephBucketNotification.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephBucketNotification). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephBucketNotification and deletes it. Returns an error if one occurs. +func (c *cephBucketNotifications) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephbucketnotifications"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephBucketNotifications) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephbucketnotifications"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephBucketNotification. +func (c *cephBucketNotifications) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephBucketNotification, err error) { + result = &v1.CephBucketNotification{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephbucketnotifications"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephbuckettopic.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephbuckettopic.go new file mode 100644 index 00000000000..89ab7cd9b22 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephbuckettopic.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephBucketTopicsGetter has a method to return a CephBucketTopicInterface. +// A group's client should implement this interface. +type CephBucketTopicsGetter interface { + CephBucketTopics(namespace string) CephBucketTopicInterface +} + +// CephBucketTopicInterface has methods to work with CephBucketTopic resources. +type CephBucketTopicInterface interface { + Create(ctx context.Context, cephBucketTopic *v1.CephBucketTopic, opts metav1.CreateOptions) (*v1.CephBucketTopic, error) + Update(ctx context.Context, cephBucketTopic *v1.CephBucketTopic, opts metav1.UpdateOptions) (*v1.CephBucketTopic, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephBucketTopic, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephBucketTopicList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephBucketTopic, err error) + CephBucketTopicExpansion +} + +// cephBucketTopics implements CephBucketTopicInterface +type cephBucketTopics struct { + client rest.Interface + ns string +} + +// newCephBucketTopics returns a CephBucketTopics +func newCephBucketTopics(c *CephV1Client, namespace string) *cephBucketTopics { + return &cephBucketTopics{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephBucketTopic, and returns the corresponding cephBucketTopic object, and an error if there is any. +func (c *cephBucketTopics) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephBucketTopic, err error) { + result = &v1.CephBucketTopic{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephbuckettopics"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephBucketTopics that match those selectors. +func (c *cephBucketTopics) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephBucketTopicList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephBucketTopicList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephbuckettopics"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephBucketTopics. +func (c *cephBucketTopics) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephbuckettopics"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephBucketTopic and creates it. Returns the server's representation of the cephBucketTopic, and an error, if there is any. +func (c *cephBucketTopics) Create(ctx context.Context, cephBucketTopic *v1.CephBucketTopic, opts metav1.CreateOptions) (result *v1.CephBucketTopic, err error) { + result = &v1.CephBucketTopic{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephbuckettopics"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephBucketTopic). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephBucketTopic and updates it. Returns the server's representation of the cephBucketTopic, and an error, if there is any. +func (c *cephBucketTopics) Update(ctx context.Context, cephBucketTopic *v1.CephBucketTopic, opts metav1.UpdateOptions) (result *v1.CephBucketTopic, err error) { + result = &v1.CephBucketTopic{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephbuckettopics"). + Name(cephBucketTopic.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephBucketTopic). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephBucketTopic and deletes it. Returns an error if one occurs. +func (c *cephBucketTopics) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephbuckettopics"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephBucketTopics) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephbuckettopics"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephBucketTopic. +func (c *cephBucketTopics) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephBucketTopic, err error) { + result = &v1.CephBucketTopic{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephbuckettopics"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephclient.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephclient.go new file mode 100644 index 00000000000..db45d7ef07d --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephclient.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephClientsGetter has a method to return a CephClientInterface. +// A group's client should implement this interface. +type CephClientsGetter interface { + CephClients(namespace string) CephClientInterface +} + +// CephClientInterface has methods to work with CephClient resources. +type CephClientInterface interface { + Create(ctx context.Context, cephClient *v1.CephClient, opts metav1.CreateOptions) (*v1.CephClient, error) + Update(ctx context.Context, cephClient *v1.CephClient, opts metav1.UpdateOptions) (*v1.CephClient, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephClient, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephClientList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephClient, err error) + CephClientExpansion +} + +// cephClients implements CephClientInterface +type cephClients struct { + client rest.Interface + ns string +} + +// newCephClients returns a CephClients +func newCephClients(c *CephV1Client, namespace string) *cephClients { + return &cephClients{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephClient, and returns the corresponding cephClient object, and an error if there is any. +func (c *cephClients) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephClient, err error) { + result = &v1.CephClient{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephclients"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephClients that match those selectors. +func (c *cephClients) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephClientList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephClientList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephclients"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephClients. +func (c *cephClients) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephclients"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephClient and creates it. Returns the server's representation of the cephClient, and an error, if there is any. +func (c *cephClients) Create(ctx context.Context, cephClient *v1.CephClient, opts metav1.CreateOptions) (result *v1.CephClient, err error) { + result = &v1.CephClient{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephclients"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephClient). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephClient and updates it. Returns the server's representation of the cephClient, and an error, if there is any. +func (c *cephClients) Update(ctx context.Context, cephClient *v1.CephClient, opts metav1.UpdateOptions) (result *v1.CephClient, err error) { + result = &v1.CephClient{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephclients"). + Name(cephClient.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephClient). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephClient and deletes it. Returns an error if one occurs. +func (c *cephClients) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephclients"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephClients) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephclients"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephClient. +func (c *cephClients) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephClient, err error) { + result = &v1.CephClient{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephclients"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephcluster.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephcluster.go new file mode 100644 index 00000000000..7ebe4e2c98a --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephcluster.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephClustersGetter has a method to return a CephClusterInterface. +// A group's client should implement this interface. +type CephClustersGetter interface { + CephClusters(namespace string) CephClusterInterface +} + +// CephClusterInterface has methods to work with CephCluster resources. +type CephClusterInterface interface { + Create(ctx context.Context, cephCluster *v1.CephCluster, opts metav1.CreateOptions) (*v1.CephCluster, error) + Update(ctx context.Context, cephCluster *v1.CephCluster, opts metav1.UpdateOptions) (*v1.CephCluster, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephCluster, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephClusterList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephCluster, err error) + CephClusterExpansion +} + +// cephClusters implements CephClusterInterface +type cephClusters struct { + client rest.Interface + ns string +} + +// newCephClusters returns a CephClusters +func newCephClusters(c *CephV1Client, namespace string) *cephClusters { + return &cephClusters{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephCluster, and returns the corresponding cephCluster object, and an error if there is any. +func (c *cephClusters) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephCluster, err error) { + result = &v1.CephCluster{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephclusters"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephClusters that match those selectors. +func (c *cephClusters) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephClusterList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephClusterList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephclusters"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephClusters. +func (c *cephClusters) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephclusters"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephCluster and creates it. Returns the server's representation of the cephCluster, and an error, if there is any. +func (c *cephClusters) Create(ctx context.Context, cephCluster *v1.CephCluster, opts metav1.CreateOptions) (result *v1.CephCluster, err error) { + result = &v1.CephCluster{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephclusters"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephCluster). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephCluster and updates it. Returns the server's representation of the cephCluster, and an error, if there is any. +func (c *cephClusters) Update(ctx context.Context, cephCluster *v1.CephCluster, opts metav1.UpdateOptions) (result *v1.CephCluster, err error) { + result = &v1.CephCluster{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephclusters"). + Name(cephCluster.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephCluster). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephCluster and deletes it. Returns an error if one occurs. +func (c *cephClusters) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephclusters"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephClusters) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephclusters"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephCluster. +func (c *cephClusters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephCluster, err error) { + result = &v1.CephCluster{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephclusters"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephcosidriver.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephcosidriver.go new file mode 100644 index 00000000000..7e084f52140 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephcosidriver.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephCOSIDriversGetter has a method to return a CephCOSIDriverInterface. +// A group's client should implement this interface. +type CephCOSIDriversGetter interface { + CephCOSIDrivers(namespace string) CephCOSIDriverInterface +} + +// CephCOSIDriverInterface has methods to work with CephCOSIDriver resources. +type CephCOSIDriverInterface interface { + Create(ctx context.Context, cephCOSIDriver *v1.CephCOSIDriver, opts metav1.CreateOptions) (*v1.CephCOSIDriver, error) + Update(ctx context.Context, cephCOSIDriver *v1.CephCOSIDriver, opts metav1.UpdateOptions) (*v1.CephCOSIDriver, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephCOSIDriver, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephCOSIDriverList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephCOSIDriver, err error) + CephCOSIDriverExpansion +} + +// cephCOSIDrivers implements CephCOSIDriverInterface +type cephCOSIDrivers struct { + client rest.Interface + ns string +} + +// newCephCOSIDrivers returns a CephCOSIDrivers +func newCephCOSIDrivers(c *CephV1Client, namespace string) *cephCOSIDrivers { + return &cephCOSIDrivers{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephCOSIDriver, and returns the corresponding cephCOSIDriver object, and an error if there is any. +func (c *cephCOSIDrivers) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephCOSIDriver, err error) { + result = &v1.CephCOSIDriver{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephcosidrivers"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephCOSIDrivers that match those selectors. +func (c *cephCOSIDrivers) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephCOSIDriverList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephCOSIDriverList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephcosidrivers"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephCOSIDrivers. +func (c *cephCOSIDrivers) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephcosidrivers"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephCOSIDriver and creates it. Returns the server's representation of the cephCOSIDriver, and an error, if there is any. +func (c *cephCOSIDrivers) Create(ctx context.Context, cephCOSIDriver *v1.CephCOSIDriver, opts metav1.CreateOptions) (result *v1.CephCOSIDriver, err error) { + result = &v1.CephCOSIDriver{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephcosidrivers"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephCOSIDriver). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephCOSIDriver and updates it. Returns the server's representation of the cephCOSIDriver, and an error, if there is any. +func (c *cephCOSIDrivers) Update(ctx context.Context, cephCOSIDriver *v1.CephCOSIDriver, opts metav1.UpdateOptions) (result *v1.CephCOSIDriver, err error) { + result = &v1.CephCOSIDriver{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephcosidrivers"). + Name(cephCOSIDriver.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephCOSIDriver). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephCOSIDriver and deletes it. Returns an error if one occurs. +func (c *cephCOSIDrivers) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephcosidrivers"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephCOSIDrivers) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephcosidrivers"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephCOSIDriver. +func (c *cephCOSIDrivers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephCOSIDriver, err error) { + result = &v1.CephCOSIDriver{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephcosidrivers"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephfilesystem.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephfilesystem.go new file mode 100644 index 00000000000..1dccce1ef26 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephfilesystem.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephFilesystemsGetter has a method to return a CephFilesystemInterface. +// A group's client should implement this interface. +type CephFilesystemsGetter interface { + CephFilesystems(namespace string) CephFilesystemInterface +} + +// CephFilesystemInterface has methods to work with CephFilesystem resources. +type CephFilesystemInterface interface { + Create(ctx context.Context, cephFilesystem *v1.CephFilesystem, opts metav1.CreateOptions) (*v1.CephFilesystem, error) + Update(ctx context.Context, cephFilesystem *v1.CephFilesystem, opts metav1.UpdateOptions) (*v1.CephFilesystem, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephFilesystem, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephFilesystemList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephFilesystem, err error) + CephFilesystemExpansion +} + +// cephFilesystems implements CephFilesystemInterface +type cephFilesystems struct { + client rest.Interface + ns string +} + +// newCephFilesystems returns a CephFilesystems +func newCephFilesystems(c *CephV1Client, namespace string) *cephFilesystems { + return &cephFilesystems{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephFilesystem, and returns the corresponding cephFilesystem object, and an error if there is any. +func (c *cephFilesystems) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephFilesystem, err error) { + result = &v1.CephFilesystem{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephfilesystems"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephFilesystems that match those selectors. +func (c *cephFilesystems) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephFilesystemList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephFilesystemList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephfilesystems"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephFilesystems. +func (c *cephFilesystems) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephfilesystems"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephFilesystem and creates it. Returns the server's representation of the cephFilesystem, and an error, if there is any. +func (c *cephFilesystems) Create(ctx context.Context, cephFilesystem *v1.CephFilesystem, opts metav1.CreateOptions) (result *v1.CephFilesystem, err error) { + result = &v1.CephFilesystem{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephfilesystems"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephFilesystem). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephFilesystem and updates it. Returns the server's representation of the cephFilesystem, and an error, if there is any. +func (c *cephFilesystems) Update(ctx context.Context, cephFilesystem *v1.CephFilesystem, opts metav1.UpdateOptions) (result *v1.CephFilesystem, err error) { + result = &v1.CephFilesystem{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephfilesystems"). + Name(cephFilesystem.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephFilesystem). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephFilesystem and deletes it. Returns an error if one occurs. +func (c *cephFilesystems) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephfilesystems"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephFilesystems) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephfilesystems"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephFilesystem. +func (c *cephFilesystems) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephFilesystem, err error) { + result = &v1.CephFilesystem{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephfilesystems"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephfilesystemmirror.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephfilesystemmirror.go new file mode 100644 index 00000000000..867b42f0925 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephfilesystemmirror.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephFilesystemMirrorsGetter has a method to return a CephFilesystemMirrorInterface. +// A group's client should implement this interface. +type CephFilesystemMirrorsGetter interface { + CephFilesystemMirrors(namespace string) CephFilesystemMirrorInterface +} + +// CephFilesystemMirrorInterface has methods to work with CephFilesystemMirror resources. +type CephFilesystemMirrorInterface interface { + Create(ctx context.Context, cephFilesystemMirror *v1.CephFilesystemMirror, opts metav1.CreateOptions) (*v1.CephFilesystemMirror, error) + Update(ctx context.Context, cephFilesystemMirror *v1.CephFilesystemMirror, opts metav1.UpdateOptions) (*v1.CephFilesystemMirror, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephFilesystemMirror, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephFilesystemMirrorList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephFilesystemMirror, err error) + CephFilesystemMirrorExpansion +} + +// cephFilesystemMirrors implements CephFilesystemMirrorInterface +type cephFilesystemMirrors struct { + client rest.Interface + ns string +} + +// newCephFilesystemMirrors returns a CephFilesystemMirrors +func newCephFilesystemMirrors(c *CephV1Client, namespace string) *cephFilesystemMirrors { + return &cephFilesystemMirrors{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephFilesystemMirror, and returns the corresponding cephFilesystemMirror object, and an error if there is any. +func (c *cephFilesystemMirrors) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephFilesystemMirror, err error) { + result = &v1.CephFilesystemMirror{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephfilesystemmirrors"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephFilesystemMirrors that match those selectors. +func (c *cephFilesystemMirrors) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephFilesystemMirrorList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephFilesystemMirrorList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephfilesystemmirrors"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephFilesystemMirrors. +func (c *cephFilesystemMirrors) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephfilesystemmirrors"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephFilesystemMirror and creates it. Returns the server's representation of the cephFilesystemMirror, and an error, if there is any. +func (c *cephFilesystemMirrors) Create(ctx context.Context, cephFilesystemMirror *v1.CephFilesystemMirror, opts metav1.CreateOptions) (result *v1.CephFilesystemMirror, err error) { + result = &v1.CephFilesystemMirror{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephfilesystemmirrors"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephFilesystemMirror). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephFilesystemMirror and updates it. Returns the server's representation of the cephFilesystemMirror, and an error, if there is any. +func (c *cephFilesystemMirrors) Update(ctx context.Context, cephFilesystemMirror *v1.CephFilesystemMirror, opts metav1.UpdateOptions) (result *v1.CephFilesystemMirror, err error) { + result = &v1.CephFilesystemMirror{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephfilesystemmirrors"). + Name(cephFilesystemMirror.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephFilesystemMirror). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephFilesystemMirror and deletes it. Returns an error if one occurs. +func (c *cephFilesystemMirrors) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephfilesystemmirrors"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephFilesystemMirrors) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephfilesystemmirrors"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephFilesystemMirror. +func (c *cephFilesystemMirrors) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephFilesystemMirror, err error) { + result = &v1.CephFilesystemMirror{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephfilesystemmirrors"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephfilesystemsubvolumegroup.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephfilesystemsubvolumegroup.go new file mode 100644 index 00000000000..80a66e56aa8 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephfilesystemsubvolumegroup.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephFilesystemSubVolumeGroupsGetter has a method to return a CephFilesystemSubVolumeGroupInterface. +// A group's client should implement this interface. +type CephFilesystemSubVolumeGroupsGetter interface { + CephFilesystemSubVolumeGroups(namespace string) CephFilesystemSubVolumeGroupInterface +} + +// CephFilesystemSubVolumeGroupInterface has methods to work with CephFilesystemSubVolumeGroup resources. +type CephFilesystemSubVolumeGroupInterface interface { + Create(ctx context.Context, cephFilesystemSubVolumeGroup *v1.CephFilesystemSubVolumeGroup, opts metav1.CreateOptions) (*v1.CephFilesystemSubVolumeGroup, error) + Update(ctx context.Context, cephFilesystemSubVolumeGroup *v1.CephFilesystemSubVolumeGroup, opts metav1.UpdateOptions) (*v1.CephFilesystemSubVolumeGroup, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephFilesystemSubVolumeGroup, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephFilesystemSubVolumeGroupList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephFilesystemSubVolumeGroup, err error) + CephFilesystemSubVolumeGroupExpansion +} + +// cephFilesystemSubVolumeGroups implements CephFilesystemSubVolumeGroupInterface +type cephFilesystemSubVolumeGroups struct { + client rest.Interface + ns string +} + +// newCephFilesystemSubVolumeGroups returns a CephFilesystemSubVolumeGroups +func newCephFilesystemSubVolumeGroups(c *CephV1Client, namespace string) *cephFilesystemSubVolumeGroups { + return &cephFilesystemSubVolumeGroups{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephFilesystemSubVolumeGroup, and returns the corresponding cephFilesystemSubVolumeGroup object, and an error if there is any. +func (c *cephFilesystemSubVolumeGroups) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephFilesystemSubVolumeGroup, err error) { + result = &v1.CephFilesystemSubVolumeGroup{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephfilesystemsubvolumegroups"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephFilesystemSubVolumeGroups that match those selectors. +func (c *cephFilesystemSubVolumeGroups) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephFilesystemSubVolumeGroupList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephFilesystemSubVolumeGroupList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephfilesystemsubvolumegroups"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephFilesystemSubVolumeGroups. +func (c *cephFilesystemSubVolumeGroups) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephfilesystemsubvolumegroups"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephFilesystemSubVolumeGroup and creates it. Returns the server's representation of the cephFilesystemSubVolumeGroup, and an error, if there is any. +func (c *cephFilesystemSubVolumeGroups) Create(ctx context.Context, cephFilesystemSubVolumeGroup *v1.CephFilesystemSubVolumeGroup, opts metav1.CreateOptions) (result *v1.CephFilesystemSubVolumeGroup, err error) { + result = &v1.CephFilesystemSubVolumeGroup{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephfilesystemsubvolumegroups"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephFilesystemSubVolumeGroup). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephFilesystemSubVolumeGroup and updates it. Returns the server's representation of the cephFilesystemSubVolumeGroup, and an error, if there is any. +func (c *cephFilesystemSubVolumeGroups) Update(ctx context.Context, cephFilesystemSubVolumeGroup *v1.CephFilesystemSubVolumeGroup, opts metav1.UpdateOptions) (result *v1.CephFilesystemSubVolumeGroup, err error) { + result = &v1.CephFilesystemSubVolumeGroup{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephfilesystemsubvolumegroups"). + Name(cephFilesystemSubVolumeGroup.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephFilesystemSubVolumeGroup). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephFilesystemSubVolumeGroup and deletes it. Returns an error if one occurs. +func (c *cephFilesystemSubVolumeGroups) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephfilesystemsubvolumegroups"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephFilesystemSubVolumeGroups) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephfilesystemsubvolumegroups"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephFilesystemSubVolumeGroup. +func (c *cephFilesystemSubVolumeGroups) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephFilesystemSubVolumeGroup, err error) { + result = &v1.CephFilesystemSubVolumeGroup{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephfilesystemsubvolumegroups"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephnfs.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephnfs.go new file mode 100644 index 00000000000..bc435165428 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephnfs.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephNFSesGetter has a method to return a CephNFSInterface. +// A group's client should implement this interface. +type CephNFSesGetter interface { + CephNFSes(namespace string) CephNFSInterface +} + +// CephNFSInterface has methods to work with CephNFS resources. +type CephNFSInterface interface { + Create(ctx context.Context, cephNFS *v1.CephNFS, opts metav1.CreateOptions) (*v1.CephNFS, error) + Update(ctx context.Context, cephNFS *v1.CephNFS, opts metav1.UpdateOptions) (*v1.CephNFS, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephNFS, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephNFSList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephNFS, err error) + CephNFSExpansion +} + +// cephNFSes implements CephNFSInterface +type cephNFSes struct { + client rest.Interface + ns string +} + +// newCephNFSes returns a CephNFSes +func newCephNFSes(c *CephV1Client, namespace string) *cephNFSes { + return &cephNFSes{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephNFS, and returns the corresponding cephNFS object, and an error if there is any. +func (c *cephNFSes) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephNFS, err error) { + result = &v1.CephNFS{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephnfses"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephNFSes that match those selectors. +func (c *cephNFSes) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephNFSList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephNFSList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephnfses"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephNFSes. +func (c *cephNFSes) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephnfses"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephNFS and creates it. Returns the server's representation of the cephNFS, and an error, if there is any. +func (c *cephNFSes) Create(ctx context.Context, cephNFS *v1.CephNFS, opts metav1.CreateOptions) (result *v1.CephNFS, err error) { + result = &v1.CephNFS{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephnfses"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephNFS). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephNFS and updates it. Returns the server's representation of the cephNFS, and an error, if there is any. +func (c *cephNFSes) Update(ctx context.Context, cephNFS *v1.CephNFS, opts metav1.UpdateOptions) (result *v1.CephNFS, err error) { + result = &v1.CephNFS{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephnfses"). + Name(cephNFS.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephNFS). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephNFS and deletes it. Returns an error if one occurs. +func (c *cephNFSes) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephnfses"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephNFSes) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephnfses"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephNFS. +func (c *cephNFSes) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephNFS, err error) { + result = &v1.CephNFS{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephnfses"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectrealm.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectrealm.go new file mode 100644 index 00000000000..a408ab8526c --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectrealm.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephObjectRealmsGetter has a method to return a CephObjectRealmInterface. +// A group's client should implement this interface. +type CephObjectRealmsGetter interface { + CephObjectRealms(namespace string) CephObjectRealmInterface +} + +// CephObjectRealmInterface has methods to work with CephObjectRealm resources. +type CephObjectRealmInterface interface { + Create(ctx context.Context, cephObjectRealm *v1.CephObjectRealm, opts metav1.CreateOptions) (*v1.CephObjectRealm, error) + Update(ctx context.Context, cephObjectRealm *v1.CephObjectRealm, opts metav1.UpdateOptions) (*v1.CephObjectRealm, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephObjectRealm, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephObjectRealmList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephObjectRealm, err error) + CephObjectRealmExpansion +} + +// cephObjectRealms implements CephObjectRealmInterface +type cephObjectRealms struct { + client rest.Interface + ns string +} + +// newCephObjectRealms returns a CephObjectRealms +func newCephObjectRealms(c *CephV1Client, namespace string) *cephObjectRealms { + return &cephObjectRealms{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephObjectRealm, and returns the corresponding cephObjectRealm object, and an error if there is any. +func (c *cephObjectRealms) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephObjectRealm, err error) { + result = &v1.CephObjectRealm{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephobjectrealms"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephObjectRealms that match those selectors. +func (c *cephObjectRealms) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephObjectRealmList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephObjectRealmList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephobjectrealms"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephObjectRealms. +func (c *cephObjectRealms) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephobjectrealms"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephObjectRealm and creates it. Returns the server's representation of the cephObjectRealm, and an error, if there is any. +func (c *cephObjectRealms) Create(ctx context.Context, cephObjectRealm *v1.CephObjectRealm, opts metav1.CreateOptions) (result *v1.CephObjectRealm, err error) { + result = &v1.CephObjectRealm{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephobjectrealms"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephObjectRealm). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephObjectRealm and updates it. Returns the server's representation of the cephObjectRealm, and an error, if there is any. +func (c *cephObjectRealms) Update(ctx context.Context, cephObjectRealm *v1.CephObjectRealm, opts metav1.UpdateOptions) (result *v1.CephObjectRealm, err error) { + result = &v1.CephObjectRealm{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephobjectrealms"). + Name(cephObjectRealm.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephObjectRealm). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephObjectRealm and deletes it. Returns an error if one occurs. +func (c *cephObjectRealms) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephobjectrealms"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephObjectRealms) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephobjectrealms"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephObjectRealm. +func (c *cephObjectRealms) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephObjectRealm, err error) { + result = &v1.CephObjectRealm{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephobjectrealms"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectstore.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectstore.go new file mode 100644 index 00000000000..7b315636352 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectstore.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephObjectStoresGetter has a method to return a CephObjectStoreInterface. +// A group's client should implement this interface. +type CephObjectStoresGetter interface { + CephObjectStores(namespace string) CephObjectStoreInterface +} + +// CephObjectStoreInterface has methods to work with CephObjectStore resources. +type CephObjectStoreInterface interface { + Create(ctx context.Context, cephObjectStore *v1.CephObjectStore, opts metav1.CreateOptions) (*v1.CephObjectStore, error) + Update(ctx context.Context, cephObjectStore *v1.CephObjectStore, opts metav1.UpdateOptions) (*v1.CephObjectStore, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephObjectStore, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephObjectStoreList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephObjectStore, err error) + CephObjectStoreExpansion +} + +// cephObjectStores implements CephObjectStoreInterface +type cephObjectStores struct { + client rest.Interface + ns string +} + +// newCephObjectStores returns a CephObjectStores +func newCephObjectStores(c *CephV1Client, namespace string) *cephObjectStores { + return &cephObjectStores{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephObjectStore, and returns the corresponding cephObjectStore object, and an error if there is any. +func (c *cephObjectStores) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephObjectStore, err error) { + result = &v1.CephObjectStore{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephobjectstores"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephObjectStores that match those selectors. +func (c *cephObjectStores) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephObjectStoreList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephObjectStoreList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephobjectstores"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephObjectStores. +func (c *cephObjectStores) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephobjectstores"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephObjectStore and creates it. Returns the server's representation of the cephObjectStore, and an error, if there is any. +func (c *cephObjectStores) Create(ctx context.Context, cephObjectStore *v1.CephObjectStore, opts metav1.CreateOptions) (result *v1.CephObjectStore, err error) { + result = &v1.CephObjectStore{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephobjectstores"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephObjectStore). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephObjectStore and updates it. Returns the server's representation of the cephObjectStore, and an error, if there is any. +func (c *cephObjectStores) Update(ctx context.Context, cephObjectStore *v1.CephObjectStore, opts metav1.UpdateOptions) (result *v1.CephObjectStore, err error) { + result = &v1.CephObjectStore{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephobjectstores"). + Name(cephObjectStore.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephObjectStore). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephObjectStore and deletes it. Returns an error if one occurs. +func (c *cephObjectStores) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephobjectstores"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephObjectStores) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephobjectstores"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephObjectStore. +func (c *cephObjectStores) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephObjectStore, err error) { + result = &v1.CephObjectStore{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephobjectstores"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectstoreuser.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectstoreuser.go new file mode 100644 index 00000000000..69e929c27bf --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectstoreuser.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephObjectStoreUsersGetter has a method to return a CephObjectStoreUserInterface. +// A group's client should implement this interface. +type CephObjectStoreUsersGetter interface { + CephObjectStoreUsers(namespace string) CephObjectStoreUserInterface +} + +// CephObjectStoreUserInterface has methods to work with CephObjectStoreUser resources. +type CephObjectStoreUserInterface interface { + Create(ctx context.Context, cephObjectStoreUser *v1.CephObjectStoreUser, opts metav1.CreateOptions) (*v1.CephObjectStoreUser, error) + Update(ctx context.Context, cephObjectStoreUser *v1.CephObjectStoreUser, opts metav1.UpdateOptions) (*v1.CephObjectStoreUser, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephObjectStoreUser, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephObjectStoreUserList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephObjectStoreUser, err error) + CephObjectStoreUserExpansion +} + +// cephObjectStoreUsers implements CephObjectStoreUserInterface +type cephObjectStoreUsers struct { + client rest.Interface + ns string +} + +// newCephObjectStoreUsers returns a CephObjectStoreUsers +func newCephObjectStoreUsers(c *CephV1Client, namespace string) *cephObjectStoreUsers { + return &cephObjectStoreUsers{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephObjectStoreUser, and returns the corresponding cephObjectStoreUser object, and an error if there is any. +func (c *cephObjectStoreUsers) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephObjectStoreUser, err error) { + result = &v1.CephObjectStoreUser{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephobjectstoreusers"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephObjectStoreUsers that match those selectors. +func (c *cephObjectStoreUsers) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephObjectStoreUserList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephObjectStoreUserList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephobjectstoreusers"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephObjectStoreUsers. +func (c *cephObjectStoreUsers) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephobjectstoreusers"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephObjectStoreUser and creates it. Returns the server's representation of the cephObjectStoreUser, and an error, if there is any. +func (c *cephObjectStoreUsers) Create(ctx context.Context, cephObjectStoreUser *v1.CephObjectStoreUser, opts metav1.CreateOptions) (result *v1.CephObjectStoreUser, err error) { + result = &v1.CephObjectStoreUser{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephobjectstoreusers"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephObjectStoreUser). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephObjectStoreUser and updates it. Returns the server's representation of the cephObjectStoreUser, and an error, if there is any. +func (c *cephObjectStoreUsers) Update(ctx context.Context, cephObjectStoreUser *v1.CephObjectStoreUser, opts metav1.UpdateOptions) (result *v1.CephObjectStoreUser, err error) { + result = &v1.CephObjectStoreUser{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephobjectstoreusers"). + Name(cephObjectStoreUser.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephObjectStoreUser). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephObjectStoreUser and deletes it. Returns an error if one occurs. +func (c *cephObjectStoreUsers) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephobjectstoreusers"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephObjectStoreUsers) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephobjectstoreusers"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephObjectStoreUser. +func (c *cephObjectStoreUsers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephObjectStoreUser, err error) { + result = &v1.CephObjectStoreUser{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephobjectstoreusers"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectzone.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectzone.go new file mode 100644 index 00000000000..315d93c3be1 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectzone.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephObjectZonesGetter has a method to return a CephObjectZoneInterface. +// A group's client should implement this interface. +type CephObjectZonesGetter interface { + CephObjectZones(namespace string) CephObjectZoneInterface +} + +// CephObjectZoneInterface has methods to work with CephObjectZone resources. +type CephObjectZoneInterface interface { + Create(ctx context.Context, cephObjectZone *v1.CephObjectZone, opts metav1.CreateOptions) (*v1.CephObjectZone, error) + Update(ctx context.Context, cephObjectZone *v1.CephObjectZone, opts metav1.UpdateOptions) (*v1.CephObjectZone, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephObjectZone, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephObjectZoneList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephObjectZone, err error) + CephObjectZoneExpansion +} + +// cephObjectZones implements CephObjectZoneInterface +type cephObjectZones struct { + client rest.Interface + ns string +} + +// newCephObjectZones returns a CephObjectZones +func newCephObjectZones(c *CephV1Client, namespace string) *cephObjectZones { + return &cephObjectZones{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephObjectZone, and returns the corresponding cephObjectZone object, and an error if there is any. +func (c *cephObjectZones) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephObjectZone, err error) { + result = &v1.CephObjectZone{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephobjectzones"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephObjectZones that match those selectors. +func (c *cephObjectZones) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephObjectZoneList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephObjectZoneList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephobjectzones"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephObjectZones. +func (c *cephObjectZones) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephobjectzones"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephObjectZone and creates it. Returns the server's representation of the cephObjectZone, and an error, if there is any. +func (c *cephObjectZones) Create(ctx context.Context, cephObjectZone *v1.CephObjectZone, opts metav1.CreateOptions) (result *v1.CephObjectZone, err error) { + result = &v1.CephObjectZone{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephobjectzones"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephObjectZone). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephObjectZone and updates it. Returns the server's representation of the cephObjectZone, and an error, if there is any. +func (c *cephObjectZones) Update(ctx context.Context, cephObjectZone *v1.CephObjectZone, opts metav1.UpdateOptions) (result *v1.CephObjectZone, err error) { + result = &v1.CephObjectZone{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephobjectzones"). + Name(cephObjectZone.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephObjectZone). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephObjectZone and deletes it. Returns an error if one occurs. +func (c *cephObjectZones) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephobjectzones"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephObjectZones) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephobjectzones"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephObjectZone. +func (c *cephObjectZones) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephObjectZone, err error) { + result = &v1.CephObjectZone{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephobjectzones"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectzonegroup.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectzonegroup.go new file mode 100644 index 00000000000..11899408a36 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephobjectzonegroup.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephObjectZoneGroupsGetter has a method to return a CephObjectZoneGroupInterface. +// A group's client should implement this interface. +type CephObjectZoneGroupsGetter interface { + CephObjectZoneGroups(namespace string) CephObjectZoneGroupInterface +} + +// CephObjectZoneGroupInterface has methods to work with CephObjectZoneGroup resources. +type CephObjectZoneGroupInterface interface { + Create(ctx context.Context, cephObjectZoneGroup *v1.CephObjectZoneGroup, opts metav1.CreateOptions) (*v1.CephObjectZoneGroup, error) + Update(ctx context.Context, cephObjectZoneGroup *v1.CephObjectZoneGroup, opts metav1.UpdateOptions) (*v1.CephObjectZoneGroup, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephObjectZoneGroup, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephObjectZoneGroupList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephObjectZoneGroup, err error) + CephObjectZoneGroupExpansion +} + +// cephObjectZoneGroups implements CephObjectZoneGroupInterface +type cephObjectZoneGroups struct { + client rest.Interface + ns string +} + +// newCephObjectZoneGroups returns a CephObjectZoneGroups +func newCephObjectZoneGroups(c *CephV1Client, namespace string) *cephObjectZoneGroups { + return &cephObjectZoneGroups{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephObjectZoneGroup, and returns the corresponding cephObjectZoneGroup object, and an error if there is any. +func (c *cephObjectZoneGroups) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephObjectZoneGroup, err error) { + result = &v1.CephObjectZoneGroup{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephobjectzonegroups"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephObjectZoneGroups that match those selectors. +func (c *cephObjectZoneGroups) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephObjectZoneGroupList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephObjectZoneGroupList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephobjectzonegroups"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephObjectZoneGroups. +func (c *cephObjectZoneGroups) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephobjectzonegroups"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephObjectZoneGroup and creates it. Returns the server's representation of the cephObjectZoneGroup, and an error, if there is any. +func (c *cephObjectZoneGroups) Create(ctx context.Context, cephObjectZoneGroup *v1.CephObjectZoneGroup, opts metav1.CreateOptions) (result *v1.CephObjectZoneGroup, err error) { + result = &v1.CephObjectZoneGroup{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephobjectzonegroups"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephObjectZoneGroup). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephObjectZoneGroup and updates it. Returns the server's representation of the cephObjectZoneGroup, and an error, if there is any. +func (c *cephObjectZoneGroups) Update(ctx context.Context, cephObjectZoneGroup *v1.CephObjectZoneGroup, opts metav1.UpdateOptions) (result *v1.CephObjectZoneGroup, err error) { + result = &v1.CephObjectZoneGroup{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephobjectzonegroups"). + Name(cephObjectZoneGroup.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephObjectZoneGroup). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephObjectZoneGroup and deletes it. Returns an error if one occurs. +func (c *cephObjectZoneGroups) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephobjectzonegroups"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephObjectZoneGroups) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephobjectzonegroups"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephObjectZoneGroup. +func (c *cephObjectZoneGroups) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephObjectZoneGroup, err error) { + result = &v1.CephObjectZoneGroup{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephobjectzonegroups"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephrbdmirror.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephrbdmirror.go new file mode 100644 index 00000000000..524e8a98f50 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/cephrbdmirror.go @@ -0,0 +1,178 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" + scheme "github.com/rook/rook/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CephRBDMirrorsGetter has a method to return a CephRBDMirrorInterface. +// A group's client should implement this interface. +type CephRBDMirrorsGetter interface { + CephRBDMirrors(namespace string) CephRBDMirrorInterface +} + +// CephRBDMirrorInterface has methods to work with CephRBDMirror resources. +type CephRBDMirrorInterface interface { + Create(ctx context.Context, cephRBDMirror *v1.CephRBDMirror, opts metav1.CreateOptions) (*v1.CephRBDMirror, error) + Update(ctx context.Context, cephRBDMirror *v1.CephRBDMirror, opts metav1.UpdateOptions) (*v1.CephRBDMirror, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CephRBDMirror, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CephRBDMirrorList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephRBDMirror, err error) + CephRBDMirrorExpansion +} + +// cephRBDMirrors implements CephRBDMirrorInterface +type cephRBDMirrors struct { + client rest.Interface + ns string +} + +// newCephRBDMirrors returns a CephRBDMirrors +func newCephRBDMirrors(c *CephV1Client, namespace string) *cephRBDMirrors { + return &cephRBDMirrors{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cephRBDMirror, and returns the corresponding cephRBDMirror object, and an error if there is any. +func (c *cephRBDMirrors) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CephRBDMirror, err error) { + result = &v1.CephRBDMirror{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephrbdmirrors"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CephRBDMirrors that match those selectors. +func (c *cephRBDMirrors) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CephRBDMirrorList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CephRBDMirrorList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cephrbdmirrors"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cephRBDMirrors. +func (c *cephRBDMirrors) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cephrbdmirrors"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cephRBDMirror and creates it. Returns the server's representation of the cephRBDMirror, and an error, if there is any. +func (c *cephRBDMirrors) Create(ctx context.Context, cephRBDMirror *v1.CephRBDMirror, opts metav1.CreateOptions) (result *v1.CephRBDMirror, err error) { + result = &v1.CephRBDMirror{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cephrbdmirrors"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephRBDMirror). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cephRBDMirror and updates it. Returns the server's representation of the cephRBDMirror, and an error, if there is any. +func (c *cephRBDMirrors) Update(ctx context.Context, cephRBDMirror *v1.CephRBDMirror, opts metav1.UpdateOptions) (result *v1.CephRBDMirror, err error) { + result = &v1.CephRBDMirror{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cephrbdmirrors"). + Name(cephRBDMirror.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cephRBDMirror). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cephRBDMirror and deletes it. Returns an error if one occurs. +func (c *cephRBDMirrors) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cephrbdmirrors"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cephRBDMirrors) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cephrbdmirrors"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cephRBDMirror. +func (c *cephRBDMirrors) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CephRBDMirror, err error) { + result = &v1.CephRBDMirror{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cephrbdmirrors"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/doc.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/doc.go new file mode 100644 index 00000000000..3af5d054f10 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1 diff --git a/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/generated_expansion.go b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/generated_expansion.go new file mode 100644 index 00000000000..ca470183bb1 --- /dev/null +++ b/vendor/github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1/generated_expansion.go @@ -0,0 +1,53 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +type CephBlockPoolExpansion interface{} + +type CephBlockPoolRadosNamespaceExpansion interface{} + +type CephBucketNotificationExpansion interface{} + +type CephBucketTopicExpansion interface{} + +type CephCOSIDriverExpansion interface{} + +type CephClientExpansion interface{} + +type CephClusterExpansion interface{} + +type CephFilesystemExpansion interface{} + +type CephFilesystemMirrorExpansion interface{} + +type CephFilesystemSubVolumeGroupExpansion interface{} + +type CephNFSExpansion interface{} + +type CephObjectRealmExpansion interface{} + +type CephObjectStoreExpansion interface{} + +type CephObjectStoreUserExpansion interface{} + +type CephObjectZoneExpansion interface{} + +type CephObjectZoneGroupExpansion interface{} + +type CephRBDMirrorExpansion interface{} diff --git a/vendor/go.uber.org/zap/.golangci.yml b/vendor/go.uber.org/zap/.golangci.yml index fbc6df79065..2346df13517 100644 --- a/vendor/go.uber.org/zap/.golangci.yml +++ b/vendor/go.uber.org/zap/.golangci.yml @@ -17,7 +17,7 @@ linters: - unused # Our own extras: - - gofmt + - gofumpt - nolintlint # lints nolint directives - revive diff --git a/vendor/go.uber.org/zap/.readme.tmpl b/vendor/go.uber.org/zap/.readme.tmpl index 92aa65d660b..a4da2c2c5f8 100644 --- a/vendor/go.uber.org/zap/.readme.tmpl +++ b/vendor/go.uber.org/zap/.readme.tmpl @@ -1,7 +1,15 @@ # :zap: zap [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] +
+ Blazing fast, structured, leveled logging in Go. +![Zap logo](assets/logo.png) + +[![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] + +
+ ## Installation `go get -u go.uber.org/zap` @@ -92,7 +100,7 @@ standard.
-Released under the [MIT License](LICENSE.txt). +Released under the [MIT License](LICENSE). 1 In particular, keep in mind that we may be benchmarking against slightly older versions of other packages. Versions are @@ -106,4 +114,3 @@ pinned in the [benchmarks/go.mod][] file. [↩](#anchor-versions) [cov]: https://codecov.io/gh/uber-go/zap [benchmarking suite]: https://github.com/uber-go/zap/tree/master/benchmarks [benchmarks/go.mod]: https://github.com/uber-go/zap/blob/master/benchmarks/go.mod - diff --git a/vendor/go.uber.org/zap/CHANGELOG.md b/vendor/go.uber.org/zap/CHANGELOG.md index 11b46597612..6d6cd5f4d70 100644 --- a/vendor/go.uber.org/zap/CHANGELOG.md +++ b/vendor/go.uber.org/zap/CHANGELOG.md @@ -3,14 +3,30 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.27.0 (20 Feb 2024) +Enhancements: +* [#1378][]: Add `WithLazy` method for `SugaredLogger`. +* [#1399][]: zaptest: Add `NewTestingWriter` for customizing TestingWriter with more flexibility than `NewLogger`. +* [#1406][]: Add `Log`, `Logw`, `Logln` methods for `SugaredLogger`. +* [#1416][]: Add `WithPanicHook` option for testing panic logs. + +Thanks to @defval, @dimmo, @arxeiss, and @MKrupauskas for their contributions to this release. + +[#1378]: https://github.com/uber-go/zap/pull/1378 +[#1399]: https://github.com/uber-go/zap/pull/1399 +[#1406]: https://github.com/uber-go/zap/pull/1406 +[#1416]: https://github.com/uber-go/zap/pull/1416 + ## 1.26.0 (14 Sep 2023) Enhancements: +* [#1297][]: Add Dict as a Field. * [#1319][]: Add `WithLazy` method to `Logger` which lazily evaluates the structured context. * [#1350][]: String encoding is much (~50%) faster now. -Thanks to @jquirke, @cdvr1993 for their contributions to this release. +Thanks to @hhk7734, @jquirke, and @cdvr1993 for their contributions to this release. +[#1297]: https://github.com/uber-go/zap/pull/1297 [#1319]: https://github.com/uber-go/zap/pull/1319 [#1350]: https://github.com/uber-go/zap/pull/1350 @@ -25,7 +41,7 @@ Enhancements: * [#1273][]: Add `Name` to `Logger` which returns the Logger's name if one is set. * [#1281][]: Add `zap/exp/expfield` package which contains helper methods `Str` and `Strs` for constructing String-like zap.Fields. -* [#1310][]: Reduce stack size on `Any`. +* [#1310][]: Reduce stack size on `Any`. Thanks to @knight42, @dzakaammar, @bcspragu, and @rexywork for their contributions to this release. @@ -352,7 +368,7 @@ to this release. [#675]: https://github.com/uber-go/zap/pull/675 [#704]: https://github.com/uber-go/zap/pull/704 -## v1.9.1 (06 Aug 2018) +## 1.9.1 (06 Aug 2018) Bugfixes: @@ -360,7 +376,7 @@ Bugfixes: [#614]: https://github.com/uber-go/zap/pull/614 -## v1.9.0 (19 Jul 2018) +## 1.9.0 (19 Jul 2018) Enhancements: * [#602][]: Reduce number of allocations when logging with reflection. @@ -373,7 +389,7 @@ Thanks to @nfarah86, @AlekSi, @JeanMertz, @philippgille, @etsangsplk, and [#572]: https://github.com/uber-go/zap/pull/572 [#606]: https://github.com/uber-go/zap/pull/606 -## v1.8.0 (13 Apr 2018) +## 1.8.0 (13 Apr 2018) Enhancements: * [#508][]: Make log level configurable when redirecting the standard @@ -391,14 +407,14 @@ Thanks to @DiSiqueira and @djui for their contributions to this release. [#577]: https://github.com/uber-go/zap/pull/577 [#574]: https://github.com/uber-go/zap/pull/574 -## v1.7.1 (25 Sep 2017) +## 1.7.1 (25 Sep 2017) Bugfixes: * [#504][]: Store strings when using AddByteString with the map encoder. [#504]: https://github.com/uber-go/zap/pull/504 -## v1.7.0 (21 Sep 2017) +## 1.7.0 (21 Sep 2017) Enhancements: @@ -407,7 +423,7 @@ Enhancements: [#487]: https://github.com/uber-go/zap/pull/487 -## v1.6.0 (30 Aug 2017) +## 1.6.0 (30 Aug 2017) Enhancements: @@ -418,7 +434,7 @@ Enhancements: [#490]: https://github.com/uber-go/zap/pull/490 [#491]: https://github.com/uber-go/zap/pull/491 -## v1.5.0 (22 Jul 2017) +## 1.5.0 (22 Jul 2017) Enhancements: @@ -436,7 +452,7 @@ Thanks to @richard-tunein and @pavius for their contributions to this release. [#460]: https://github.com/uber-go/zap/pull/460 [#470]: https://github.com/uber-go/zap/pull/470 -## v1.4.1 (08 Jun 2017) +## 1.4.1 (08 Jun 2017) This release fixes two bugs. @@ -448,7 +464,7 @@ Bugfixes: [#435]: https://github.com/uber-go/zap/pull/435 [#444]: https://github.com/uber-go/zap/pull/444 -## v1.4.0 (12 May 2017) +## 1.4.0 (12 May 2017) This release adds a few small features and is fully backward-compatible. @@ -464,7 +480,7 @@ Enhancements: [#425]: https://github.com/uber-go/zap/pull/425 [#431]: https://github.com/uber-go/zap/pull/431 -## v1.3.0 (25 Apr 2017) +## 1.3.0 (25 Apr 2017) This release adds an enhancement to zap's testing helpers as well as the ability to marshal an AtomicLevel. It is fully backward-compatible. @@ -478,7 +494,7 @@ Enhancements: [#415]: https://github.com/uber-go/zap/pull/415 [#416]: https://github.com/uber-go/zap/pull/416 -## v1.2.0 (13 Apr 2017) +## 1.2.0 (13 Apr 2017) This release adds a gRPC compatibility wrapper. It is fully backward-compatible. @@ -489,7 +505,7 @@ Enhancements: [#402]: https://github.com/uber-go/zap/pull/402 -## v1.1.0 (31 Mar 2017) +## 1.1.0 (31 Mar 2017) This release fixes two bugs and adds some enhancements to zap's testing helpers. It is fully backward-compatible. @@ -510,7 +526,7 @@ Thanks to @moitias for contributing to this release. [#396]: https://github.com/uber-go/zap/pull/396 [#386]: https://github.com/uber-go/zap/pull/386 -## v1.0.0 (14 Mar 2017) +## 1.0.0 (14 Mar 2017) This is zap's first stable release. All exported APIs are now final, and no further breaking changes will be made in the 1.x release series. Anyone using a @@ -569,7 +585,7 @@ contributions to this release. [#365]: https://github.com/uber-go/zap/pull/365 [#372]: https://github.com/uber-go/zap/pull/372 -## v1.0.0-rc.3 (7 Mar 2017) +## 1.0.0-rc.3 (7 Mar 2017) This is the third release candidate for zap's stable release. There are no breaking changes. @@ -595,7 +611,7 @@ Thanks to @ansel1 and @suyash for their contributions to this release. [#353]: https://github.com/uber-go/zap/pull/353 [#311]: https://github.com/uber-go/zap/pull/311 -## v1.0.0-rc.2 (21 Feb 2017) +## 1.0.0-rc.2 (21 Feb 2017) This is the second release candidate for zap's stable release. It includes two breaking changes. @@ -641,7 +657,7 @@ Thanks to @skipor and @chapsuk for their contributions to this release. [#326]: https://github.com/uber-go/zap/pull/326 [#300]: https://github.com/uber-go/zap/pull/300 -## v1.0.0-rc.1 (14 Feb 2017) +## 1.0.0-rc.1 (14 Feb 2017) This is the first release candidate for zap's stable release. There are multiple breaking changes and improvements from the pre-release version. Most notably: @@ -661,7 +677,7 @@ breaking changes and improvements from the pre-release version. Most notably: * Sampling is more accurate, and doesn't depend on the standard library's shared timer heap. -## v0.1.0-beta.1 (6 Feb 2017) +## 0.1.0-beta.1 (6 Feb 2017) This is a minor version, tagged to allow users to pin to the pre-1.0 APIs and upgrade at their leisure. Since this is the first tagged release, there are no diff --git a/vendor/go.uber.org/zap/LICENSE.txt b/vendor/go.uber.org/zap/LICENSE similarity index 100% rename from vendor/go.uber.org/zap/LICENSE.txt rename to vendor/go.uber.org/zap/LICENSE diff --git a/vendor/go.uber.org/zap/README.md b/vendor/go.uber.org/zap/README.md index 9de08927be9..ea6a48d4589 100644 --- a/vendor/go.uber.org/zap/README.md +++ b/vendor/go.uber.org/zap/README.md @@ -1,7 +1,16 @@ -# :zap: zap [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] +# :zap: zap + + +
Blazing fast, structured, leveled logging in Go. +![Zap logo](assets/logo.png) + +[![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] + +
+ ## Installation `go get -u go.uber.org/zap` @@ -66,41 +75,44 @@ Log a message and 10 fields: | Package | Time | Time % to zap | Objects Allocated | | :------ | :--: | :-----------: | :---------------: | -| :zap: zap | 1744 ns/op | +0% | 5 allocs/op -| :zap: zap (sugared) | 2483 ns/op | +42% | 10 allocs/op -| zerolog | 918 ns/op | -47% | 1 allocs/op -| go-kit | 5590 ns/op | +221% | 57 allocs/op -| slog | 5640 ns/op | +223% | 40 allocs/op -| apex/log | 21184 ns/op | +1115% | 63 allocs/op -| logrus | 24338 ns/op | +1296% | 79 allocs/op -| log15 | 26054 ns/op | +1394% | 74 allocs/op +| :zap: zap | 656 ns/op | +0% | 5 allocs/op +| :zap: zap (sugared) | 935 ns/op | +43% | 10 allocs/op +| zerolog | 380 ns/op | -42% | 1 allocs/op +| go-kit | 2249 ns/op | +243% | 57 allocs/op +| slog (LogAttrs) | 2479 ns/op | +278% | 40 allocs/op +| slog | 2481 ns/op | +278% | 42 allocs/op +| apex/log | 9591 ns/op | +1362% | 63 allocs/op +| log15 | 11393 ns/op | +1637% | 75 allocs/op +| logrus | 11654 ns/op | +1677% | 79 allocs/op Log a message with a logger that already has 10 fields of context: | Package | Time | Time % to zap | Objects Allocated | | :------ | :--: | :-----------: | :---------------: | -| :zap: zap | 193 ns/op | +0% | 0 allocs/op -| :zap: zap (sugared) | 227 ns/op | +18% | 1 allocs/op -| zerolog | 81 ns/op | -58% | 0 allocs/op -| slog | 322 ns/op | +67% | 0 allocs/op -| go-kit | 5377 ns/op | +2686% | 56 allocs/op -| apex/log | 19518 ns/op | +10013% | 53 allocs/op -| log15 | 19812 ns/op | +10165% | 70 allocs/op -| logrus | 21997 ns/op | +11297% | 68 allocs/op +| :zap: zap | 67 ns/op | +0% | 0 allocs/op +| :zap: zap (sugared) | 84 ns/op | +25% | 1 allocs/op +| zerolog | 35 ns/op | -48% | 0 allocs/op +| slog | 193 ns/op | +188% | 0 allocs/op +| slog (LogAttrs) | 200 ns/op | +199% | 0 allocs/op +| go-kit | 2460 ns/op | +3572% | 56 allocs/op +| log15 | 9038 ns/op | +13390% | 70 allocs/op +| apex/log | 9068 ns/op | +13434% | 53 allocs/op +| logrus | 10521 ns/op | +15603% | 68 allocs/op Log a static string, without any context or `printf`-style templating: | Package | Time | Time % to zap | Objects Allocated | | :------ | :--: | :-----------: | :---------------: | -| :zap: zap | 165 ns/op | +0% | 0 allocs/op -| :zap: zap (sugared) | 212 ns/op | +28% | 1 allocs/op -| zerolog | 95 ns/op | -42% | 0 allocs/op -| slog | 296 ns/op | +79% | 0 allocs/op -| go-kit | 415 ns/op | +152% | 9 allocs/op -| standard library | 422 ns/op | +156% | 2 allocs/op -| apex/log | 1601 ns/op | +870% | 5 allocs/op -| logrus | 3017 ns/op | +1728% | 23 allocs/op -| log15 | 3469 ns/op | +2002% | 20 allocs/op +| :zap: zap | 63 ns/op | +0% | 0 allocs/op +| :zap: zap (sugared) | 81 ns/op | +29% | 1 allocs/op +| zerolog | 32 ns/op | -49% | 0 allocs/op +| standard library | 124 ns/op | +97% | 1 allocs/op +| slog | 196 ns/op | +211% | 0 allocs/op +| slog (LogAttrs) | 200 ns/op | +217% | 0 allocs/op +| go-kit | 213 ns/op | +238% | 9 allocs/op +| apex/log | 771 ns/op | +1124% | 5 allocs/op +| logrus | 1439 ns/op | +2184% | 23 allocs/op +| log15 | 2069 ns/op | +3184% | 20 allocs/op ## Development Status: Stable @@ -120,7 +132,7 @@ standard.
-Released under the [MIT License](LICENSE.txt). +Released under the [MIT License](LICENSE). 1 In particular, keep in mind that we may be benchmarking against slightly older versions of other packages. Versions are @@ -134,4 +146,3 @@ pinned in the [benchmarks/go.mod][] file. [↩](#anchor-versions) [cov]: https://codecov.io/gh/uber-go/zap [benchmarking suite]: https://github.com/uber-go/zap/tree/master/benchmarks [benchmarks/go.mod]: https://github.com/uber-go/zap/blob/master/benchmarks/go.mod - diff --git a/vendor/go.uber.org/zap/buffer/buffer.go b/vendor/go.uber.org/zap/buffer/buffer.go index 27fb5cd5dab..0b8540c2138 100644 --- a/vendor/go.uber.org/zap/buffer/buffer.go +++ b/vendor/go.uber.org/zap/buffer/buffer.go @@ -42,7 +42,7 @@ func (b *Buffer) AppendByte(v byte) { b.bs = append(b.bs, v) } -// AppendBytes writes a single byte to the Buffer. +// AppendBytes writes the given slice of bytes to the Buffer. func (b *Buffer) AppendBytes(v []byte) { b.bs = append(b.bs, v...) } diff --git a/vendor/go.uber.org/zap/field.go b/vendor/go.uber.org/zap/field.go index c8dd3358a9c..6743930b823 100644 --- a/vendor/go.uber.org/zap/field.go +++ b/vendor/go.uber.org/zap/field.go @@ -460,6 +460,8 @@ func (d dictObject) MarshalLogObject(enc zapcore.ObjectEncoder) error { // - https://github.com/uber-go/zap/pull/1304 // - https://github.com/uber-go/zap/pull/1305 // - https://github.com/uber-go/zap/pull/1308 +// +// See https://github.com/golang/go/issues/62077 for upstream issue. type anyFieldC[T any] func(string, T) Field func (f anyFieldC[T]) Any(key string, val any) Field { diff --git a/vendor/go.uber.org/zap/logger.go b/vendor/go.uber.org/zap/logger.go index 6205fe48a6c..c4d30032394 100644 --- a/vendor/go.uber.org/zap/logger.go +++ b/vendor/go.uber.org/zap/logger.go @@ -43,6 +43,7 @@ type Logger struct { development bool addCaller bool + onPanic zapcore.CheckWriteHook // default is WriteThenPanic onFatal zapcore.CheckWriteHook // default is WriteThenFatal name string @@ -345,27 +346,12 @@ func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { // Set up any required terminal behavior. switch ent.Level { case zapcore.PanicLevel: - ce = ce.After(ent, zapcore.WriteThenPanic) + ce = ce.After(ent, terminalHookOverride(zapcore.WriteThenPanic, log.onPanic)) case zapcore.FatalLevel: - onFatal := log.onFatal - // nil or WriteThenNoop will lead to continued execution after - // a Fatal log entry, which is unexpected. For example, - // - // f, err := os.Open(..) - // if err != nil { - // log.Fatal("cannot open", zap.Error(err)) - // } - // fmt.Println(f.Name()) - // - // The f.Name() will panic if we continue execution after the - // log.Fatal. - if onFatal == nil || onFatal == zapcore.WriteThenNoop { - onFatal = zapcore.WriteThenFatal - } - ce = ce.After(ent, onFatal) + ce = ce.After(ent, terminalHookOverride(zapcore.WriteThenFatal, log.onFatal)) case zapcore.DPanicLevel: if log.development { - ce = ce.After(ent, zapcore.WriteThenPanic) + ce = ce.After(ent, terminalHookOverride(zapcore.WriteThenPanic, log.onPanic)) } } @@ -430,3 +416,20 @@ func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { return ce } + +func terminalHookOverride(defaultHook, override zapcore.CheckWriteHook) zapcore.CheckWriteHook { + // A nil or WriteThenNoop hook will lead to continued execution after + // a Panic or Fatal log entry, which is unexpected. For example, + // + // f, err := os.Open(..) + // if err != nil { + // log.Fatal("cannot open", zap.Error(err)) + // } + // fmt.Println(f.Name()) + // + // The f.Name() will panic if we continue execution after the log.Fatal. + if override == nil || override == zapcore.WriteThenNoop { + return defaultHook + } + return override +} diff --git a/vendor/go.uber.org/zap/options.go b/vendor/go.uber.org/zap/options.go index c4f3bca3d20..43d357ac902 100644 --- a/vendor/go.uber.org/zap/options.go +++ b/vendor/go.uber.org/zap/options.go @@ -132,6 +132,21 @@ func IncreaseLevel(lvl zapcore.LevelEnabler) Option { }) } +// WithPanicHook sets a CheckWriteHook to run on Panic/DPanic logs. +// Zap will call this hook after writing a log statement with a Panic/DPanic level. +// +// For example, the following builds a logger that will exit the current +// goroutine after writing a Panic/DPanic log message, but it will not start a panic. +// +// zap.New(core, zap.WithPanicHook(zapcore.WriteThenGoexit)) +// +// This is useful for testing Panic/DPanic log output. +func WithPanicHook(hook zapcore.CheckWriteHook) Option { + return optionFunc(func(log *Logger) { + log.onPanic = hook + }) +} + // OnFatal sets the action to take on fatal logs. // // Deprecated: Use [WithFatalHook] instead. diff --git a/vendor/go.uber.org/zap/sugar.go b/vendor/go.uber.org/zap/sugar.go index 00ac5fe3ac8..8904cd0871e 100644 --- a/vendor/go.uber.org/zap/sugar.go +++ b/vendor/go.uber.org/zap/sugar.go @@ -115,6 +115,21 @@ func (s *SugaredLogger) With(args ...interface{}) *SugaredLogger { return &SugaredLogger{base: s.base.With(s.sweetenFields(args)...)} } +// WithLazy adds a variadic number of fields to the logging context lazily. +// The fields are evaluated only if the logger is further chained with [With] +// or is written to with any of the log level methods. +// Until that occurs, the logger may retain references to objects inside the fields, +// and logging will reflect the state of an object at the time of logging, +// not the time of WithLazy(). +// +// Similar to [With], fields added to the child don't affect the parent, +// and vice versa. Also, the keys in key-value pairs should be strings. In development, +// passing a non-string key panics, while in production it logs an error and skips the pair. +// Passing an orphaned key has the same behavior. +func (s *SugaredLogger) WithLazy(args ...interface{}) *SugaredLogger { + return &SugaredLogger{base: s.base.WithLazy(s.sweetenFields(args)...)} +} + // Level reports the minimum enabled level for this logger. // // For NopLoggers, this is [zapcore.InvalidLevel]. @@ -122,6 +137,12 @@ func (s *SugaredLogger) Level() zapcore.Level { return zapcore.LevelOf(s.base.core) } +// Log logs the provided arguments at provided level. +// Spaces are added between arguments when neither is a string. +func (s *SugaredLogger) Log(lvl zapcore.Level, args ...interface{}) { + s.log(lvl, "", args, nil) +} + // Debug logs the provided arguments at [DebugLevel]. // Spaces are added between arguments when neither is a string. func (s *SugaredLogger) Debug(args ...interface{}) { @@ -165,6 +186,12 @@ func (s *SugaredLogger) Fatal(args ...interface{}) { s.log(FatalLevel, "", args, nil) } +// Logf formats the message according to the format specifier +// and logs it at provided level. +func (s *SugaredLogger) Logf(lvl zapcore.Level, template string, args ...interface{}) { + s.log(lvl, template, args, nil) +} + // Debugf formats the message according to the format specifier // and logs it at [DebugLevel]. func (s *SugaredLogger) Debugf(template string, args ...interface{}) { @@ -208,6 +235,12 @@ func (s *SugaredLogger) Fatalf(template string, args ...interface{}) { s.log(FatalLevel, template, args, nil) } +// Logw logs a message with some additional context. The variadic key-value +// pairs are treated as they are in With. +func (s *SugaredLogger) Logw(lvl zapcore.Level, msg string, keysAndValues ...interface{}) { + s.log(lvl, msg, nil, keysAndValues) +} + // Debugw logs a message with some additional context. The variadic key-value // pairs are treated as they are in With. // @@ -255,6 +288,12 @@ func (s *SugaredLogger) Fatalw(msg string, keysAndValues ...interface{}) { s.log(FatalLevel, msg, nil, keysAndValues) } +// Logln logs a message at provided level. +// Spaces are always added between arguments. +func (s *SugaredLogger) Logln(lvl zapcore.Level, args ...interface{}) { + s.logln(lvl, args, nil) +} + // Debugln logs a message at [DebugLevel]. // Spaces are always added between arguments. func (s *SugaredLogger) Debugln(args ...interface{}) { diff --git a/vendor/go.uber.org/zap/zapcore/console_encoder.go b/vendor/go.uber.org/zap/zapcore/console_encoder.go index 8ca0bfaf561..cc2b4e07b93 100644 --- a/vendor/go.uber.org/zap/zapcore/console_encoder.go +++ b/vendor/go.uber.org/zap/zapcore/console_encoder.go @@ -77,7 +77,7 @@ func (c consoleEncoder) EncodeEntry(ent Entry, fields []Field) (*buffer.Buffer, // If this ever becomes a performance bottleneck, we can implement // ArrayEncoder for our plain-text format. arr := getSliceEncoder() - if c.TimeKey != "" && c.EncodeTime != nil { + if c.TimeKey != "" && c.EncodeTime != nil && !ent.Time.IsZero() { c.EncodeTime(ent.Time, arr) } if c.LevelKey != "" && c.EncodeLevel != nil { diff --git a/vendor/go.uber.org/zap/zapcore/encoder.go b/vendor/go.uber.org/zap/zapcore/encoder.go index 5769ff3e4e5..04462541565 100644 --- a/vendor/go.uber.org/zap/zapcore/encoder.go +++ b/vendor/go.uber.org/zap/zapcore/encoder.go @@ -37,6 +37,9 @@ const DefaultLineEnding = "\n" const OmitKey = "" // A LevelEncoder serializes a Level to a primitive type. +// +// This function must make exactly one call +// to a PrimitiveArrayEncoder's Append* method. type LevelEncoder func(Level, PrimitiveArrayEncoder) // LowercaseLevelEncoder serializes a Level to a lowercase string. For example, @@ -90,6 +93,9 @@ func (e *LevelEncoder) UnmarshalText(text []byte) error { } // A TimeEncoder serializes a time.Time to a primitive type. +// +// This function must make exactly one call +// to a PrimitiveArrayEncoder's Append* method. type TimeEncoder func(time.Time, PrimitiveArrayEncoder) // EpochTimeEncoder serializes a time.Time to a floating-point number of seconds @@ -219,6 +225,9 @@ func (e *TimeEncoder) UnmarshalJSON(data []byte) error { } // A DurationEncoder serializes a time.Duration to a primitive type. +// +// This function must make exactly one call +// to a PrimitiveArrayEncoder's Append* method. type DurationEncoder func(time.Duration, PrimitiveArrayEncoder) // SecondsDurationEncoder serializes a time.Duration to a floating-point number of seconds elapsed. @@ -262,6 +271,9 @@ func (e *DurationEncoder) UnmarshalText(text []byte) error { } // A CallerEncoder serializes an EntryCaller to a primitive type. +// +// This function must make exactly one call +// to a PrimitiveArrayEncoder's Append* method. type CallerEncoder func(EntryCaller, PrimitiveArrayEncoder) // FullCallerEncoder serializes a caller in /full/path/to/package/file:line @@ -292,6 +304,9 @@ func (e *CallerEncoder) UnmarshalText(text []byte) error { // A NameEncoder serializes a period-separated logger name to a primitive // type. +// +// This function must make exactly one call +// to a PrimitiveArrayEncoder's Append* method. type NameEncoder func(string, PrimitiveArrayEncoder) // FullNameEncoder serializes the logger name as-is. diff --git a/vendor/go.uber.org/zap/zapcore/field.go b/vendor/go.uber.org/zap/zapcore/field.go index 95bdb0a126f..308c9781ed1 100644 --- a/vendor/go.uber.org/zap/zapcore/field.go +++ b/vendor/go.uber.org/zap/zapcore/field.go @@ -47,7 +47,7 @@ const ( ByteStringType // Complex128Type indicates that the field carries a complex128. Complex128Type - // Complex64Type indicates that the field carries a complex128. + // Complex64Type indicates that the field carries a complex64. Complex64Type // DurationType indicates that the field carries a time.Duration. DurationType diff --git a/vendor/go.uber.org/zap/zapcore/json_encoder.go b/vendor/go.uber.org/zap/zapcore/json_encoder.go index c8ab86979b0..9685169b2ea 100644 --- a/vendor/go.uber.org/zap/zapcore/json_encoder.go +++ b/vendor/go.uber.org/zap/zapcore/json_encoder.go @@ -372,7 +372,7 @@ func (enc *jsonEncoder) EncodeEntry(ent Entry, fields []Field) (*buffer.Buffer, final.AppendString(ent.Level.String()) } } - if final.TimeKey != "" { + if final.TimeKey != "" && !ent.Time.IsZero() { final.AddTime(final.TimeKey, ent.Time) } if ent.LoggerName != "" && final.NameKey != "" { diff --git a/vendor/go.uber.org/zap/zapgrpc/zapgrpc.go b/vendor/go.uber.org/zap/zapgrpc/zapgrpc.go index 6823773b727..682de254de2 100644 --- a/vendor/go.uber.org/zap/zapgrpc/zapgrpc.go +++ b/vendor/go.uber.org/zap/zapgrpc/zapgrpc.go @@ -36,16 +36,14 @@ const ( grpcLvlFatal ) -var ( - // _grpcToZapLevel maps gRPC log levels to zap log levels. - // See https://pkg.go.dev/go.uber.org/zap@v1.16.0/zapcore#Level - _grpcToZapLevel = map[int]zapcore.Level{ - grpcLvlInfo: zapcore.InfoLevel, - grpcLvlWarn: zapcore.WarnLevel, - grpcLvlError: zapcore.ErrorLevel, - grpcLvlFatal: zapcore.FatalLevel, - } -) +// _grpcToZapLevel maps gRPC log levels to zap log levels. +// See https://pkg.go.dev/go.uber.org/zap@v1.16.0/zapcore#Level +var _grpcToZapLevel = map[int]zapcore.Level{ + grpcLvlInfo: zapcore.InfoLevel, + grpcLvlWarn: zapcore.WarnLevel, + grpcLvlError: zapcore.ErrorLevel, + grpcLvlFatal: zapcore.FatalLevel, +} // An Option overrides a Logger's default configuration. type Option interface { diff --git a/vendor/modules.txt b/vendor/modules.txt index 743f5ddd857..56bbabd8709 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -66,14 +66,17 @@ github.com/AzureAD/microsoft-authentication-library-for-go/apps/public ## explicit; go 1.15 github.com/IBM/keyprotect-go-client github.com/IBM/keyprotect-go-client/iam +# github.com/Masterminds/semver/v3 v3.2.1 +## explicit; go 1.18 +github.com/Masterminds/semver/v3 # github.com/NYTimes/gziphandler v1.1.1 ## explicit; go 1.11 github.com/NYTimes/gziphandler -# github.com/ansel1/merry v1.6.2 -## explicit; go 1.12 +# github.com/ansel1/merry v1.8.0 +## explicit; go 1.18 github.com/ansel1/merry -# github.com/ansel1/merry/v2 v2.0.1 -## explicit; go 1.12 +# github.com/ansel1/merry/v2 v2.2.0 +## explicit; go 1.18 github.com/ansel1/merry/v2 # github.com/antlr4-go/antlr/v4 v4.13.0 ## explicit; go 1.20 @@ -197,7 +200,7 @@ github.com/blang/semver/v4 # github.com/cenkalti/backoff/v4 v4.3.0 ## explicit; go 1.18 github.com/cenkalti/backoff/v4 -# github.com/ceph/ceph-csi/api v0.0.0-00010101000000-000000000000 => ./api +# github.com/ceph/ceph-csi/api v0.0.0-20231227104434-06f9a98b7a83 => ./api ## explicit; go 1.22.5 github.com/ceph/ceph-csi/api/deploy/kubernetes github.com/ceph/ceph-csi/api/deploy/kubernetes/cephfs @@ -228,6 +231,18 @@ github.com/cespare/xxhash/v2 # github.com/container-storage-interface/spec v1.10.0 ## explicit; go 1.18 github.com/container-storage-interface/spec/lib/go/csi +# github.com/containernetworking/cni v1.2.0-rc1 +## explicit; go 1.18 +github.com/containernetworking/cni/libcni +github.com/containernetworking/cni/pkg/invoke +github.com/containernetworking/cni/pkg/types +github.com/containernetworking/cni/pkg/types/020 +github.com/containernetworking/cni/pkg/types/040 +github.com/containernetworking/cni/pkg/types/100 +github.com/containernetworking/cni/pkg/types/create +github.com/containernetworking/cni/pkg/types/internal +github.com/containernetworking/cni/pkg/utils +github.com/containernetworking/cni/pkg/version # github.com/coreos/go-semver v0.3.1 ## explicit; go 1.8 github.com/coreos/go-semver/semver @@ -249,7 +264,7 @@ github.com/davecgh/go-spew/spew # github.com/distribution/reference v0.5.0 ## explicit; go 1.20 github.com/distribution/reference -# github.com/emicklei/go-restful/v3 v3.11.0 +# github.com/emicklei/go-restful/v3 v3.12.1 ## explicit; go 1.13 github.com/emicklei/go-restful/v3 github.com/emicklei/go-restful/v3/log @@ -257,6 +272,9 @@ github.com/emicklei/go-restful/v3/log ## explicit; go 1.18 github.com/evanphx/json-patch/v5 github.com/evanphx/json-patch/v5/internal/json +# github.com/fatih/color v1.17.0 +## explicit; go 1.17 +github.com/fatih/color # github.com/felixge/httpsnoop v1.0.4 ## explicit; go 1.13 github.com/felixge/httpsnoop @@ -266,7 +284,7 @@ github.com/fsnotify/fsnotify # github.com/fxamacker/cbor/v2 v2.7.0 ## explicit; go 1.17 github.com/fxamacker/cbor/v2 -# github.com/gemalto/flume v0.13.0 +# github.com/gemalto/flume v0.13.1 ## explicit; go 1.14 github.com/gemalto/flume # github.com/gemalto/kmip-go v0.0.10 @@ -291,15 +309,15 @@ github.com/go-logr/logr/funcr # github.com/go-logr/stdr v1.2.2 ## explicit; go 1.16 github.com/go-logr/stdr -# github.com/go-openapi/jsonpointer v0.19.6 -## explicit; go 1.13 +# github.com/go-openapi/jsonpointer v0.21.0 +## explicit; go 1.20 github.com/go-openapi/jsonpointer -# github.com/go-openapi/jsonreference v0.20.2 -## explicit; go 1.13 +# github.com/go-openapi/jsonreference v0.21.0 +## explicit; go 1.20 github.com/go-openapi/jsonreference github.com/go-openapi/jsonreference/internal -# github.com/go-openapi/swag v0.22.4 -## explicit; go 1.18 +# github.com/go-openapi/swag v0.23.0 +## explicit; go 1.20 github.com/go-openapi/swag # github.com/go-task/slim-sprig/v3 v3.0.0 ## explicit; go 1.20 @@ -316,6 +334,9 @@ github.com/golang-jwt/jwt/v5 # github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da ## explicit github.com/golang/groupcache/lru +# github.com/golang/mock v1.6.0 +## explicit; go 1.11 +github.com/golang/mock/gomock # github.com/golang/protobuf v1.5.4 ## explicit; go 1.17 github.com/golang/protobuf/descriptor @@ -411,14 +432,14 @@ github.com/hashicorp/go-retryablehttp # github.com/hashicorp/go-rootcerts v1.0.2 ## explicit; go 1.12 github.com/hashicorp/go-rootcerts -# github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 -## explicit; go 1.16 +# github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8 +## explicit; go 1.20 github.com/hashicorp/go-secure-stdlib/parseutil # github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 ## explicit; go 1.16 github.com/hashicorp/go-secure-stdlib/strutil -# github.com/hashicorp/go-sockaddr v1.0.2 -## explicit +# github.com/hashicorp/go-sockaddr v1.0.6 +## explicit; go 1.19 github.com/hashicorp/go-sockaddr # github.com/hashicorp/hcl v1.0.1-vault-5 ## explicit; go 1.15 @@ -434,13 +455,13 @@ github.com/hashicorp/hcl/json/token # github.com/hashicorp/vault/api v1.15.0 ## explicit; go 1.21 github.com/hashicorp/vault/api -# github.com/hashicorp/vault/api/auth/approle v0.5.0 +# github.com/hashicorp/vault/api/auth/approle v0.6.0 ## explicit; go 1.16 github.com/hashicorp/vault/api/auth/approle -# github.com/hashicorp/vault/api/auth/kubernetes v0.5.0 +# github.com/hashicorp/vault/api/auth/kubernetes v0.6.0 ## explicit; go 1.16 github.com/hashicorp/vault/api/auth/kubernetes -# github.com/imdario/mergo v0.3.13 +# github.com/imdario/mergo v0.3.16 ## explicit; go 1.13 github.com/imdario/mergo # github.com/inconshreveable/mousetrap v1.1.0 @@ -455,6 +476,11 @@ github.com/josharian/intern # github.com/json-iterator/go v1.1.12 ## explicit; go 1.12 github.com/json-iterator/go +# github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.0 +## explicit; go 1.21 +github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io +github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1 +github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils # github.com/klauspost/compress v1.17.9 ## explicit; go 1.20 github.com/klauspost/compress @@ -464,6 +490,10 @@ github.com/klauspost/compress/internal/cpuinfo github.com/klauspost/compress/internal/snapref github.com/klauspost/compress/zstd github.com/klauspost/compress/zstd/internal/xxhash +# github.com/kube-object-storage/lib-bucket-provisioner v0.0.0-20221122204822-d1a8c34382f1 +## explicit; go 1.13 +github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io +github.com/kube-object-storage/lib-bucket-provisioner/pkg/apis/objectbucket.io/v1alpha1 # github.com/kubernetes-csi/csi-lib-utils v0.19.0 ## explicit; go 1.22.5 github.com/kubernetes-csi/csi-lib-utils/connection @@ -481,7 +511,7 @@ github.com/kubernetes-csi/external-snapshotter/client/v8/clientset/versioned/typ ## explicit; go 1.11 github.com/kylelemons/godebug/diff github.com/kylelemons/godebug/pretty -# github.com/libopenstorage/secrets v0.0.0-20231011182615-5f4b25ceede1 +# github.com/libopenstorage/secrets v0.0.0-20240416031220-a17cf7f72c6c ## explicit; go 1.13 github.com/libopenstorage/secrets github.com/libopenstorage/secrets/vault @@ -568,7 +598,7 @@ github.com/opencontainers/go-digest github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label github.com/opencontainers/selinux/pkg/pwalkdir -# github.com/openshift/api v0.0.0-20240115183315-0793e918179d +# github.com/openshift/api v0.0.0-20240301093301-ce10821dc999 ## explicit; go 1.21 github.com/openshift/api/security/v1 # github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c @@ -606,6 +636,19 @@ github.com/prometheus/common/model github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs github.com/prometheus/procfs/internal/util +# github.com/rook/kubectl-rook-ceph v0.9.2 +## explicit; go 1.22.0 +github.com/rook/kubectl-rook-ceph/pkg/k8sutil +github.com/rook/kubectl-rook-ceph/pkg/logging +# github.com/rook/rook v1.15.4 +## explicit; go 1.22.5 +github.com/rook/rook/pkg/client/clientset/versioned +github.com/rook/rook/pkg/client/clientset/versioned/scheme +github.com/rook/rook/pkg/client/clientset/versioned/typed/ceph.rook.io/v1 +# github.com/rook/rook/pkg/apis v0.0.0-20231204200402-5287527732f7 +## explicit; go 1.20 +github.com/rook/rook/pkg/apis/ceph.rook.io +github.com/rook/rook/pkg/apis/ceph.rook.io/v1 # github.com/ryanuber/go-glob v1.0.0 ## explicit github.com/ryanuber/go-glob @@ -714,7 +757,7 @@ go.opentelemetry.io/proto/otlp/trace/v1 # go.uber.org/multierr v1.11.0 ## explicit; go 1.19 go.uber.org/multierr -# go.uber.org/zap v1.26.0 +# go.uber.org/zap v1.27.0 ## explicit; go 1.19 go.uber.org/zap go.uber.org/zap/buffer @@ -1654,7 +1697,7 @@ k8s.io/kms/apis/v1beta1 k8s.io/kms/apis/v2 k8s.io/kms/pkg/service k8s.io/kms/pkg/util -# k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 +# k8s.io/kube-openapi v0.0.0-20240620174524-b456828f718b ## explicit; go 1.20 k8s.io/kube-openapi/pkg/builder k8s.io/kube-openapi/pkg/builder3 From 21397b09ad29b885b235f96999938fa67da88027 Mon Sep 17 00:00:00 2001 From: Oded Viner Date: Mon, 4 Nov 2024 19:42:23 +0200 Subject: [PATCH 2/3] WIP: Debugging code on live cluster Signed-off-by: Oded Viner --- e2e/e2e_test.go | 28 +++------------------------- e2e/pod.go | 34 ++++++++++------------------------ e2e/rbd_helper.go | 28 ++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 49 deletions(-) diff --git a/e2e/e2e_test.go b/e2e/e2e_test.go index 327a7df9a2a..aeddae74c1c 100644 --- a/e2e/e2e_test.go +++ b/e2e/e2e_test.go @@ -17,9 +17,6 @@ limitations under the License. package e2e import ( - "bytes" - "context" - "encoding/json" "flag" "fmt" "log" @@ -73,37 +70,18 @@ func setDefaultKubeconfig() { } func TestE2E(t *testing.T) { - f := framework.NewDefaultFramework("some tests") - ctx := context.TODO() - clientsets := getClientsets(ctx) - var stdout, stderr bytes.Buffer - fruits := []string{"health"} - - err := execCmdInPod(ctx, clientsets, "ceph", "rook-ceph-tools-68bf47bc65-57pmq", "rook-ceph-tools", "rook-ceph", "rook-ceph", fruits, &stdout, &stderr, true) - if err != nil { - fmt.Println(err) - } - var imgInfos []string - err = json.Unmarshal(stdout.Bytes(), &imgInfos) - validateRBDImageCount(f, 1, "a") t.Parallel() RegisterFailHandler(Fail) RunSpecs(t, "E2e Suite") } func TestDebug(t *testing.T) { - f := framework.NewDefaultFramework("some tests") - ctx := context.TODO() - clientsets := getClientsets(ctx) - var stdout, stderr bytes.Buffer - fruits := []string{"health"} - err := execCmdInPod(ctx, clientsets, "ceph", "rook-ceph-tools-68bf47bc65-57pmq", "rook-ceph-tools", "rook-ceph", "rook-ceph", fruits, &stdout, &stderr, true) + f := framework.NewDefaultFramework("debug test") + imgInfo, err := getImageInfoDebug(f) if err != nil { fmt.Println(err) } - var imgInfos []string - err = json.Unmarshal(stdout.Bytes(), &imgInfos) - validateRBDImageCount(f, 1, "a") + fmt.Println(imgInfo) } func handleFlags() { diff --git a/e2e/pod.go b/e2e/pod.go index 99fc74c3d1b..ccc8a97b2df 100644 --- a/e2e/pod.go +++ b/e2e/pod.go @@ -774,32 +774,18 @@ func getClientsets(ctx context.Context) *k8sutil.Clientsets { // execCmdInPod exec command on specific pod and wait the command's output. func execCmdInPod(ctx context.Context, clientsets *k8sutil.Clientsets, - command, podName, containerName, podNamespace, clusterNamespace string, - args []string, stdout, stderr io.Writer, returnOutput bool) error { - - if len(args) < 1 { - return fmt.Errorf("no arg passed to exec with %q command", command) - } - - cmd := []string{} - cmd = append(cmd, command) - cmd = append(cmd, args...) + commandStr string, stdout, stderr io.Writer, returnOutput bool) error { + podNamespace := "rook-ceph" + clusterNamespace := "rook-ceph" + pods, err := clientsets.Kube.CoreV1().Pods(clusterNamespace).List(ctx, metav1.ListOptions{ + LabelSelector: "app=rook-ceph-tools", + }) + if err != nil { - if containerName == "rook-ceph-tools" { - cmd = append(cmd, "--connect-timeout=10") - } else if cmd[0] == "ceph" { - if len(cmd) > 1 && cmd[1] == "daemon" { - cmd = append(cmd, "--connect-timeout=10") - } else { - cmd = append(cmd, "--connect-timeout=10", fmt.Sprintf("--conf=/var/lib/rook/%s/%s.config", clusterNamespace, clusterNamespace)) - } - } else if cmd[0] == "rbd" { - cmd = append(cmd, fmt.Sprintf("--conf=/var/lib/rook/%s/%s.config", clusterNamespace, clusterNamespace)) - } else if cmd[0] == "rados" { - cmd = append(cmd, fmt.Sprintf("--conf=/var/lib/rook/%s/%s.config", clusterNamespace, clusterNamespace)) - } else if cmd[0] == "radosgw-admin" { - cmd = append(cmd, fmt.Sprintf("--conf=/var/lib/rook/%s/%s.config", clusterNamespace, clusterNamespace)) } + cmd := strings.Fields(commandStr) + podName := pods.Items[0].ObjectMeta.Name + containerName := "rook-ceph-tools" // Prepare the API URL used to execute another process within the Pod. In // this case, we'll run a remote shell. diff --git a/e2e/rbd_helper.go b/e2e/rbd_helper.go index b35e38a432c..80a8b76fa1f 100644 --- a/e2e/rbd_helper.go +++ b/e2e/rbd_helper.go @@ -17,6 +17,7 @@ limitations under the License. package e2e import ( + "bytes" "context" "encoding/json" "fmt" @@ -1094,6 +1095,33 @@ func getImageInfo(f *framework.Framework, imageName, poolName string) (imageInfo return imgInfo, nil } +// getImageInfo queries rbd about the given image and returns its metadata, and returns +// error if provided image is not found. +func getImageInfoDebug(f *framework.Framework) (imageInfo, error) { + // rbd --format=json info [image-spec | snap-spec] + var imgInfo imageInfo + ctx := context.TODO() + clientsets := getClientsets(ctx) + var stdout, stdErr bytes.Buffer + commandStr := "rbd info --pool=replicapool csi-vol-f090b7e1-a821-4a71-a7d2-7e3e2aaea8d1 --format json" + err := execCmdInPod(ctx, clientsets, commandStr, &stdout, &stdErr, true) + stdOut := stdout.String() + if err != nil { + fmt.Println(err) + } + + if err != nil { + return imgInfo, fmt.Errorf("failed to get rbd info: %w", err) + } + err = json.Unmarshal([]byte(stdOut), &imgInfo) + if err != nil { + return imgInfo, fmt.Errorf("unmarshal failed: %w. raw buffer response: %s", + err, stdOut) + } + + return imgInfo, nil +} + // validateStripe validate the stripe count, stripe unit and object size of the // image. func validateStripe(f *framework.Framework, From ff2ff8acd015b6f58251e38f247618cc620c349c Mon Sep 17 00:00:00 2001 From: Oded Viner Date: Mon, 11 Nov 2024 10:32:32 +0200 Subject: [PATCH 3/3] fix code Signed-off-by: Oded Viner --- e2e/e2e_test.go | 2 +- e2e/pod.go | 31 +++++++++++++++++++------------ e2e/rbd_helper.go | 31 ++++++++++++++++++++----------- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/e2e/e2e_test.go b/e2e/e2e_test.go index aeddae74c1c..0fe45148aba 100644 --- a/e2e/e2e_test.go +++ b/e2e/e2e_test.go @@ -81,7 +81,7 @@ func TestDebug(t *testing.T) { if err != nil { fmt.Println(err) } - fmt.Println(imgInfo) + fmt.Printf("%+v\n", imgInfo) } func handleFlags() { diff --git a/e2e/pod.go b/e2e/pod.go index ccc8a97b2df..e349fc04c66 100644 --- a/e2e/pod.go +++ b/e2e/pod.go @@ -20,16 +20,18 @@ import ( "context" "errors" "fmt" - "github.com/rook/kubectl-rook-ceph/pkg/k8sutil" - rookclient "github.com/rook/rook/pkg/client/clientset/versioned" "io" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/tools/clientcmd" - "k8s.io/client-go/tools/remotecommand" "os" "regexp" "strings" "time" + "bytes" + + "github.com/rook/kubectl-rook-ceph/pkg/k8sutil" + rookclient "github.com/rook/rook/pkg/client/clientset/versioned" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/tools/remotecommand" v1 "k8s.io/api/core/v1" apierrs "k8s.io/apimachinery/pkg/api/errors" @@ -42,6 +44,7 @@ import ( "k8s.io/kubernetes/test/e2e/framework" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" frameworkPod "k8s.io/kubernetes/test/e2e/framework/pod" + // "k8s.io/kubernetes/test/e2e/framework/pod/output" ) const errRWOPConflict = "node has pod using PersistentVolumeClaim with the same name and ReadWriteOncePod access mode." @@ -772,16 +775,19 @@ func getClientsets(ctx context.Context) *k8sutil.Clientsets { return clientsets } -// execCmdInPod exec command on specific pod and wait the command's output. -func execCmdInPod(ctx context.Context, clientsets *k8sutil.Clientsets, - commandStr string, stdout, stderr io.Writer, returnOutput bool) error { +// execCmdInToolPodDebug exec command on specific pod and wait the command's output. +func execCmdInToolPodDebug(commandStr string) (string, string, error) { + ctx := context.TODO() + clientsets := getClientsets(ctx) podNamespace := "rook-ceph" clusterNamespace := "rook-ceph" + var stdout, stderr io.Writer = &bytes.Buffer{}, &bytes.Buffer{} + returnOutput := true pods, err := clientsets.Kube.CoreV1().Pods(clusterNamespace).List(ctx, metav1.ListOptions{ LabelSelector: "app=rook-ceph-tools", }) if err != nil { - + return "a", "a", fmt.Errorf("failed to get ceph tool pod. %w", err) } cmd := strings.Fields(commandStr) podName := pods.Items[0].ObjectMeta.Name @@ -805,7 +811,7 @@ func execCmdInPod(ctx context.Context, clientsets *k8sutil.Clientsets, exec, err := remotecommand.NewSPDYExecutor(clientsets.KubeConfig, "POST", req.URL()) if err != nil { - return fmt.Errorf("failed to create SPDYExecutor. %w", err) + return "a", "a", fmt.Errorf("failed to create SPDYExecutor. %w", err) } // returnOutput is true, the command's output will be print on shell directly with os.Stdout or os.Stderr @@ -825,7 +831,8 @@ func execCmdInPod(ctx context.Context, clientsets *k8sutil.Clientsets, }) } if err != nil { - return fmt.Errorf("failed to run command. %w", err) + return "a", "a", fmt.Errorf("failed to run command. %w", err) } - return nil + outputSting := stdout.(*bytes.Buffer) + return outputSting.String(), "" , nil } diff --git a/e2e/rbd_helper.go b/e2e/rbd_helper.go index 80a8b76fa1f..e24f2691177 100644 --- a/e2e/rbd_helper.go +++ b/e2e/rbd_helper.go @@ -17,7 +17,6 @@ limitations under the License. package e2e import ( - "bytes" "context" "encoding/json" "fmt" @@ -1064,10 +1063,23 @@ func waitToRemoveImagesFromTrash(f *framework.Framework, poolName string, t int) // imageInfo strongly typed JSON spec for image info. type imageInfo struct { - Name string `json:"name"` - StripeUnit int `json:"stripe_unit"` - StripeCount int `json:"stripe_count"` - ObjectSize int `json:"object_size"` + Name string `json:"name"` + ID string `json:"id"` + Size int64 `json:"size"` + Objects int `json:"objects"` + Order int `json:"order"` + ObjectSize int `json:"object_size"` + SnapshotCount int `json:"snapshot_count"` + BlockNamePrefix string `json:"block_name_prefix"` + Format int `json:"format"` + Features []string `json:"features"` + OpFeatures []string `json:"op_features"` + Flags []string `json:"flags"` + CreateTimestamp string `json:"create_timestamp"` + AccessTimestamp string `json:"access_timestamp"` + ModifyTimestamp string `json:"modify_timestamp"` + StripeUnit int `json:"stripe_unit"` // New field added + StripeCount int `json:"stripe_count"` // New field added } // getImageInfo queries rbd about the given image and returns its metadata, and returns @@ -1100,12 +1112,9 @@ func getImageInfo(f *framework.Framework, imageName, poolName string) (imageInfo func getImageInfoDebug(f *framework.Framework) (imageInfo, error) { // rbd --format=json info [image-spec | snap-spec] var imgInfo imageInfo - ctx := context.TODO() - clientsets := getClientsets(ctx) - var stdout, stdErr bytes.Buffer - commandStr := "rbd info --pool=replicapool csi-vol-f090b7e1-a821-4a71-a7d2-7e3e2aaea8d1 --format json" - err := execCmdInPod(ctx, clientsets, commandStr, &stdout, &stdErr, true) - stdOut := stdout.String() + commandStr := "rbd info --pool=replicapool csi-vol-a85efba1-37ed-46cf-ae64-e43bd372510b --format json" + stdOut, _ , err := execCmdInToolPodDebug(commandStr) + if err != nil { fmt.Println(err) }