diff --git a/go.mod b/go.mod index 42ce92ecbdaa..7ca108a242c9 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/onsi/ginkgo/v2 v2.13.0 github.com/onsi/gomega v1.29.0 github.com/opencontainers/go-digest v1.0.0 - github.com/openshift/api v0.0.0-20240410141538-3c0461467316 + github.com/openshift/api v0.0.0-20240415140253-c0feb35ae9fb github.com/openshift/apiserver-library-go v0.0.0-20240313131158-facc40cc7688 github.com/openshift/build-machinery-go v0.0.0-20231128094528-1e9b1b0595c8 github.com/openshift/client-go v0.0.0-20240408153607-64bd6feb83ae @@ -49,6 +49,7 @@ require ( golang.org/x/oauth2 v0.10.0 golang.org/x/sync v0.5.0 google.golang.org/grpc v1.58.3 + gopkg.in/ini.v1 v1.62.0 gopkg.in/src-d/go-git.v4 v4.13.1 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.29.0 @@ -265,7 +266,6 @@ require ( google.golang.org/protobuf v1.33.0 // indirect gopkg.in/gcfg.v1 v1.2.3 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/ini.v1 v1.62.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/src-d/go-billy.v4 v4.3.2 // indirect diff --git a/go.sum b/go.sum index 460d56e9a933..dda13579c44c 100644 --- a/go.sum +++ b/go.sum @@ -634,8 +634,8 @@ github.com/opencontainers/runtime-spec v1.0.3-0.20220909204839-494a5a6aca78 h1:R github.com/opencontainers/runtime-spec v1.0.3-0.20220909204839-494a5a6aca78/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= 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-20240410141538-3c0461467316 h1:YfatsH1e28WTbuNUl3LZl6PKCr6zBaYLR7JSxg+LJSU= -github.com/openshift/api v0.0.0-20240410141538-3c0461467316/go.mod h1:CxgbWAlvu2iQB0UmKTtRu1YfepRg1/vJ64n2DlIEVz4= +github.com/openshift/api v0.0.0-20240415140253-c0feb35ae9fb h1:VXw3qKECkLeZFJaNw5XPnAgwn8nCeLe3OeXgGHSzRsU= +github.com/openshift/api v0.0.0-20240415140253-c0feb35ae9fb/go.mod h1:CxgbWAlvu2iQB0UmKTtRu1YfepRg1/vJ64n2DlIEVz4= github.com/openshift/apiserver-library-go v0.0.0-20240313131158-facc40cc7688 h1:E7U+i+BKXjzH1bZsB5a9ueSxF/8QeLxA9ZncCb0vecs= github.com/openshift/apiserver-library-go v0.0.0-20240313131158-facc40cc7688/go.mod h1:a6meSr6htNKfmmZ8ixLmnim/JL7NkgW7rX7J2vczMp4= github.com/openshift/build-machinery-go v0.0.0-20231128094528-1e9b1b0595c8 h1:cu3YUMVGsKIyFyJGO3F6BZKGYQZpCKxAv9cBPgQAca8= diff --git a/test/extended/storage/driver_configuration.go b/test/extended/storage/driver_configuration.go new file mode 100644 index 000000000000..082153e01cd1 --- /dev/null +++ b/test/extended/storage/driver_configuration.go @@ -0,0 +1,405 @@ +package storage + +import ( + "context" + "fmt" + g "github.com/onsi/ginkgo/v2" + o "github.com/onsi/gomega" + opv1 "github.com/openshift/api/operator/v1" + exutil "github.com/openshift/origin/test/extended/util" + "gopkg.in/ini.v1" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/util/retry" + "k8s.io/kubernetes/test/e2e/framework" + e2e "k8s.io/kubernetes/test/e2e/framework" + k8simage "k8s.io/kubernetes/test/utils/image" + "k8s.io/utils/ptr" + "reflect" + "strings" + "sync" + "time" +) + +const ( + projectName = "csi-driver-configuration" + providerName = "csi.vsphere.vmware.com" +) + +// This is [Serial] because it modifies ClusterCSIDriver. +var _ = g.Describe("[sig-storage][Feature:VSphereDriverConfiguration][Serial][apigroup:operator.openshift.io] vSphere CSI Driver Configuration", func() { + defer g.GinkgoRecover() + var ( + ctx = context.Background() + oc = exutil.NewCLI(projectName) + originalDriverConfigSpec *opv1.CSIDriverConfigSpec + ) + + o.SetDefaultEventuallyTimeout(5 * time.Minute) + o.SetDefaultEventuallyPollingInterval(5 * time.Second) + + g.BeforeEach(func() { + //TODO: remove when GA + if !exutil.IsTechPreviewNoUpgrade(oc) { + g.Skip("this test is only expected to work with TechPreviewNoUpgrade clusters") + } + + if !framework.ProviderIs("vsphere") { + g.Skip("this test is only expected to work with vSphere clusters") + } + + originalClusterCSIDriver, err := oc.AdminOperatorClient().OperatorV1().ClusterCSIDrivers().Get(ctx, providerName, metav1.GetOptions{}) + o.Expect(err).NotTo(o.HaveOccurred()) + + originalDriverConfigSpec = originalClusterCSIDriver.Spec.DriverConfig.DeepCopy() + e2e.Logf("Storing original driverConfig of ClusterCSIDriver") + }) + + g.AfterEach(func() { + if originalDriverConfigSpec == nil { + return + } + + e2e.Logf("Restoring original driverConfig of ClusterCSIDriver") + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + clusterCSIDriver, err := oc.AdminOperatorClient().OperatorV1().ClusterCSIDrivers().Get(ctx, providerName, metav1.GetOptions{}) + if err != nil { + return err + } + + clusterCSIDriver.Spec.DriverConfig = *originalDriverConfigSpec + _, err = oc.AdminOperatorClient().OperatorV1().ClusterCSIDrivers().Update(ctx, clusterCSIDriver, metav1.UpdateOptions{}) + if err != nil { + return err + } + + return nil + }) + o.Expect(err).NotTo(o.HaveOccurred(), "failed to update ClusterCSIDriver") + + e2e.Logf("Successfully restored original driverConfig of ClusterCSIDriver") + }) + + g.Context("snapshot options in clusterCSIDriver should", func() { + var tests = []struct { + name string + clusterCSIDriverOptions *opv1.VSphereCSIDriverConfigSpec + cloudConfigOptions map[string]string + successfulSnapshotsCreated int // Number of snapshots that should be created successfully, 0 to skip. + }{ + { + name: "use default when unset", + clusterCSIDriverOptions: nil, + cloudConfigOptions: map[string]string{}, + successfulSnapshotsCreated: 3, + }, + { + name: "allow setting global snapshot limit", + clusterCSIDriverOptions: &opv1.VSphereCSIDriverConfigSpec{ + GlobalMaxSnapshotsPerBlockVolume: ptr.To(uint32(4)), + }, + cloudConfigOptions: map[string]string{ + "global-max-snapshots-per-block-volume": "4", + }, + successfulSnapshotsCreated: 4, + }, + { + name: "allow setting VSAN limit", + clusterCSIDriverOptions: &opv1.VSphereCSIDriverConfigSpec{ + GranularMaxSnapshotsPerBlockVolumeInVSAN: ptr.To(uint32(4)), + }, + cloudConfigOptions: map[string]string{ + "granular-max-snapshots-per-block-volume-vsan": "4", + }, + successfulSnapshotsCreated: 0, + }, + { + name: "allow setting VVOL limit", + clusterCSIDriverOptions: &opv1.VSphereCSIDriverConfigSpec{ + GranularMaxSnapshotsPerBlockVolumeInVVOL: ptr.To(uint32(4)), + }, + cloudConfigOptions: map[string]string{ + "granular-max-snapshots-per-block-volume-vvol": "4", + }, + successfulSnapshotsCreated: 0, + }, + { + name: "allow all limits to be set at once", + clusterCSIDriverOptions: &opv1.VSphereCSIDriverConfigSpec{ + GlobalMaxSnapshotsPerBlockVolume: ptr.To(uint32(5)), + GranularMaxSnapshotsPerBlockVolumeInVSAN: ptr.To(uint32(10)), + GranularMaxSnapshotsPerBlockVolumeInVVOL: ptr.To(uint32(15)), + }, + cloudConfigOptions: map[string]string{ + "global-max-snapshots-per-block-volume": "5", + "granular-max-snapshots-per-block-volume-vsan": "10", + "granular-max-snapshots-per-block-volume-vvol": "15", + }, + successfulSnapshotsCreated: 0, + }, + } + + for _, t := range tests { + t := t + g.It(fmt.Sprintf("%s", t.name), func() { + + setClusterCSIDriverSnapshotOptions(ctx, oc, t.clusterCSIDriverOptions) + o.Eventually(func() error { + return loadAndCheckCloudConf(ctx, oc, "Snapshot", t.cloudConfigOptions, t.clusterCSIDriverOptions) + }).Should(o.Succeed()) + + validateSnapshotCreation(ctx, oc, t.successfulSnapshotsCreated) + }) + } + }) +}) + +func setClusterCSIDriverSnapshotOptions(ctx context.Context, oc *exutil.CLI, clusterCSIDriverOptions *opv1.VSphereCSIDriverConfigSpec) { + e2e.Logf("updating ClusterCSIDriver driver config to: %+v", clusterCSIDriverOptions) + + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + clusterCSIDriver, err := oc.AdminOperatorClient().OperatorV1().ClusterCSIDrivers().Get(ctx, providerName, metav1.GetOptions{}) + if err != nil { + return err + } + + clusterCSIDriver.Spec.DriverConfig.VSphere = clusterCSIDriverOptions + _, err = oc.AdminOperatorClient().OperatorV1().ClusterCSIDrivers().Update(ctx, clusterCSIDriver, metav1.UpdateOptions{}) + if err != nil { + return err + } + + return nil + }) + o.Expect(err).NotTo(o.HaveOccurred(), "failed to update ClusterCSIDriver") +} + +func loadAndCheckCloudConf(ctx context.Context, oc *exutil.CLI, sectionName string, cloudConfigOptions map[string]string, clusterCSIDriverOptions *opv1.VSphereCSIDriverConfigSpec) error { + e2e.Logf("Validating cloud.conf section %s", sectionName) + + if clusterCSIDriverOptions == nil { + e2e.Logf("Skipping cloud.conf check, no snapshot options are set for the driver.") + return nil + } + + cm, err := oc.AdminKubeClient().CoreV1().ConfigMaps("openshift-cluster-csi-drivers").Get(ctx, "vsphere-csi-config", metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("failed to get ConfigMap: %v", err) + } + + cloudConfData, ok := cm.Data["cloud.conf"] + if !ok { + return fmt.Errorf("cloud.conf key not found in ConfigMap") + } + + cfg, err := ini.Load([]byte(cloudConfData)) + if err != nil { + return fmt.Errorf("failed to load cloud.conf: %v", err) + } + + section, err := cfg.GetSection(sectionName) + if err != nil { + return fmt.Errorf("section %s not found in cloud.conf: %v", sectionName, err) + } + + if !reflect.DeepEqual(section.KeysHash(), cloudConfigOptions) { + return fmt.Errorf("check of %s section in cloud.conf failed, got: %v expected: %v", sectionName, section.KeysHash(), cloudConfigOptions) + } + + e2e.Logf("Validation of %s section in cloud.conf succeeded", sectionName) + + return nil +} + +func validateSnapshotCreation(ctx context.Context, oc *exutil.CLI, successfulSnapshotsCreated int) { + e2e.Logf("Validating snapshot creation.") + + if successfulSnapshotsCreated == 0 { + e2e.Logf("Skipping snapshot validation, successfulSnapshotsCreated is set to 0 for this test.") + return + } + + pvc, err := createTestPVC(ctx, oc, oc.Namespace(), "test-pvc", "1Gi") + o.Expect(err).NotTo(o.HaveOccurred()) + defer func() { + oc.AdminKubeClient().CoreV1().PersistentVolumeClaims(oc.Namespace()).Delete(ctx, pvc.Name, metav1.DeleteOptions{}) + }() + + pod, err := createTestPod(ctx, oc, pvc.Name, oc.Namespace()) + o.Expect(err).NotTo(o.HaveOccurred()) + defer func() { oc.KubeClient().CoreV1().Pods(oc.Namespace()).Delete(ctx, pod.Name, metav1.DeleteOptions{}) }() + + // Wait for pvc to be bound. + o.Eventually(func() v1.PersistentVolumeClaimPhase { + pvc, err := oc.AdminKubeClient().CoreV1().PersistentVolumeClaims(oc.Namespace()).Get(ctx, "test-pvc", metav1.GetOptions{}) + o.Expect(err).NotTo(o.HaveOccurred()) + return pvc.Status.Phase + }).Should(o.Equal(v1.ClaimBound)) + + var wg sync.WaitGroup + var snapshotsCreated = make([]string, 0, successfulSnapshotsCreated) + for i := 0; i < successfulSnapshotsCreated; i++ { + wg.Add(1) + snapshotName := fmt.Sprintf("test-snapshot-%d", i) + snapshotsCreated = append(snapshotsCreated, snapshotName) + go func(snapshotName string) { + defer wg.Done() + err := createSnapshot(oc, oc.Namespace(), snapshotName, "test-pvc") + if err != nil { + e2e.Failf("failed to create snapshot: %v", err) + return + } + }(snapshotName) + } + wg.Wait() + + defer func() { + for _, snapshotName := range snapshotsCreated { + oc.AsAdmin().Run("delete").Args("volumesnapshot", snapshotName).Execute() + } + }() + + // Wait for snapshots to be readyToUse. + o.Eventually(func() int { + snapshotsReady := 0 + for _, snapshotName := range snapshotsCreated { + if ready, _ := isSnapshotReady(oc, snapshotName); ready { + e2e.Logf("Snapshot %s is ready", snapshotName) + snapshotsReady++ + } else { + e2e.Logf("Snapshot %s is not ready yet", snapshotName) + } + } + e2e.Logf("Snapshots ready: %d/%d", snapshotsReady, successfulSnapshotsCreated) + return snapshotsReady + }).Should(o.Equal(successfulSnapshotsCreated), "not all snapshots are ready") + + // Next snapshot creation should be over the set limit and fail. + failedSnapshotName := "test-snapshot-failed" + err = createSnapshot(oc, oc.Namespace(), failedSnapshotName, "test-pvc") + o.Expect(err).NotTo(o.HaveOccurred(), "failed to create snapshot") + + e2e.Logf("Validating that snapshot creation now fails since the limit is reached.") + + o.Eventually(func() bool { + ready := false + errMsg := "" + if ready, err = isSnapshotReady(oc, failedSnapshotName); err != nil { + return false + } + if errMsg, err = getSnapshotErrorMessage(oc, failedSnapshotName); err != nil || errMsg == "" { + return false + } + e2e.Logf("Error validation successful - snapshot: %s readyToUse: %t, error message: %s", failedSnapshotName, ready, errMsg) + return strings.Contains(errMsg, "reaches the configured maximum") && !ready + }).Should(o.BeTrue(), "snapshot creation should fail") +} + +func createTestPod(ctx context.Context, oc *exutil.CLI, pvcName string, namespace string) (*v1.Pod, error) { + allowPrivEsc := false + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod-driver-conf", + Namespace: namespace, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "test", + Image: k8simage.GetE2EImage(k8simage.BusyBox), + VolumeMounts: []v1.VolumeMount{ + { + Name: "pvc-data", + MountPath: "/mnt", + }, + }, + SecurityContext: &v1.SecurityContext{ + AllowPrivilegeEscalation: &allowPrivEsc, + SeccompProfile: &v1.SeccompProfile{ + Type: v1.SeccompProfileTypeRuntimeDefault, + }, + Capabilities: &v1.Capabilities{ + Drop: []v1.Capability{"ALL"}, + }, + }, + }, + }, + Volumes: []v1.Volume{ + { + Name: "pvc-data", + VolumeSource: v1.VolumeSource{ + PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ + ClaimName: pvcName, + }, + }, + }, + }, + }, + } + + return oc.AdminKubeClient().CoreV1().Pods(namespace).Create(ctx, pod, metav1.CreateOptions{}) +} + +func createTestPVC(ctx context.Context, oc *exutil.CLI, namespace string, pvcName string, volumeSize string) (*v1.PersistentVolumeClaim, error) { + e2e.Logf("Creating PVC %s in namespace %s with size %s", pvcName, namespace, volumeSize) + + pvc := &v1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: pvcName, + Namespace: namespace, + }, + Spec: v1.PersistentVolumeClaimSpec{ + AccessModes: []v1.PersistentVolumeAccessMode{"ReadWriteOnce"}, + Resources: v1.VolumeResourceRequirements{ + Requests: v1.ResourceList{ + v1.ResourceStorage: resource.MustParse(volumeSize), + }, + }, + }, + } + + return oc.AdminKubeClient().CoreV1().PersistentVolumeClaims(namespace).Create(ctx, pvc, metav1.CreateOptions{}) +} + +func createSnapshot(oc *exutil.CLI, namespace string, snapshotName string, pvcName string) error { + e2e.Logf("Creating snapshot %s for PVC %s in namespace %s", snapshotName, pvcName, namespace) + + snapshot := fmt.Sprintf(` +apiVersion: snapshot.storage.k8s.io/v1 +kind: VolumeSnapshot +metadata: + name: %s + namespace: %s +spec: + source: + persistentVolumeClaimName: %s +`, snapshotName, namespace, pvcName) + + err := oc.AsAdmin().Run("apply").Args("-f", "-").InputString(snapshot).Execute() + if err != nil { + return fmt.Errorf("failed to create snapshot: %v", err) + } + + return nil +} + +func isSnapshotReady(oc *exutil.CLI, snapshotName string) (bool, error) { + readyToUse, err := oc.Run("get").Args(fmt.Sprintf("volumesnapshot/%s", snapshotName), "-o", "jsonpath={.status.readyToUse}").Output() + if err != nil { + e2e.Logf("failed to get snapshot readyToUse: %v", err) + return false, err + } + + return readyToUse == "true", nil +} + +func getSnapshotErrorMessage(oc *exutil.CLI, snapshotName string) (string, error) { + errMsg, err := oc.Run("get").Args(fmt.Sprintf("volumesnapshot/%s", snapshotName), "-o", "jsonpath={.status.error.message}").Output() + if err != nil { + e2e.Logf("failed to get snapshot error message: %v", err) + return "", err + } + + return errMsg, nil +} diff --git a/test/extended/util/annotate/generated/zz_generated.annotations.go b/test/extended/util/annotate/generated/zz_generated.annotations.go index 8222ca4287b5..6be1ab39e87a 100644 --- a/test/extended/util/annotate/generated/zz_generated.annotations.go +++ b/test/extended/util/annotate/generated/zz_generated.annotations.go @@ -1579,6 +1579,16 @@ var Annotations = map[string]string{ "[sig-storage][Feature:DisableStorageClass][Serial][apigroup:operator.openshift.io] should remove the StorageClass when StorageClassState is Removed": " [Suite:openshift/conformance/serial]", + "[sig-storage][Feature:VSphereDriverConfiguration][Serial][apigroup:operator.openshift.io] vSphere CSI Driver Configuration snapshot options in clusterCSIDriver should allow all limits to be set at once": " [Suite:openshift/conformance/serial]", + + "[sig-storage][Feature:VSphereDriverConfiguration][Serial][apigroup:operator.openshift.io] vSphere CSI Driver Configuration snapshot options in clusterCSIDriver should allow setting VSAN limit": " [Suite:openshift/conformance/serial]", + + "[sig-storage][Feature:VSphereDriverConfiguration][Serial][apigroup:operator.openshift.io] vSphere CSI Driver Configuration snapshot options in clusterCSIDriver should allow setting VVOL limit": " [Suite:openshift/conformance/serial]", + + "[sig-storage][Feature:VSphereDriverConfiguration][Serial][apigroup:operator.openshift.io] vSphere CSI Driver Configuration snapshot options in clusterCSIDriver should allow setting global snapshot limit": " [Suite:openshift/conformance/serial]", + + "[sig-storage][Feature:VSphereDriverConfiguration][Serial][apigroup:operator.openshift.io] vSphere CSI Driver Configuration snapshot options in clusterCSIDriver should use default when unset": " [Suite:openshift/conformance/serial]", + "[sig-storage][Late] Metrics should report short attach times": " [Skipped:Disconnected] [Suite:openshift/conformance/parallel]", "[sig-storage][Late] Metrics should report short mount times": " [Skipped:Disconnected] [Suite:openshift/conformance/parallel]", diff --git a/vendor/github.com/openshift/api/Makefile b/vendor/github.com/openshift/api/Makefile index 3b3c94edcea3..7fd53975186a 100644 --- a/vendor/github.com/openshift/api/Makefile +++ b/vendor/github.com/openshift/api/Makefile @@ -51,6 +51,7 @@ verify-scripts: bash -x hack/verify-prerelease-lifecycle-gen.sh hack/verify-payload-crds.sh hack/verify-payload-featuregates.sh + hack/verify-promoted-features-pass-tests.sh .PHONY: verify verify: verify-scripts verify-crd-schema verify-codegen-crds diff --git a/vendor/github.com/openshift/api/config/v1/feature_gates.go b/vendor/github.com/openshift/api/config/v1/feature_gates.go index 7a9d129cfbd3..b5c7a2ce7506 100644 --- a/vendor/github.com/openshift/api/config/v1/feature_gates.go +++ b/vendor/github.com/openshift/api/config/v1/feature_gates.go @@ -595,4 +595,11 @@ var ( productScope(ocpSpecific). enableIn(TechPreviewNoUpgrade). mustRegister() + + FeatureGateVSphereDriverConfiguration = newFeatureGate("VSphereDriverConfiguration"). + reportProblemsToJiraComponent("Storage / Kubernetes External Components"). + contactPerson("rbednar"). + productScope(ocpSpecific). + enableIn(TechPreviewNoUpgrade). + mustRegister() ) diff --git a/vendor/github.com/openshift/api/features.md b/vendor/github.com/openshift/api/features.md index fd496313af5f..9f660ef265f0 100644 --- a/vendor/github.com/openshift/api/features.md +++ b/vendor/github.com/openshift/api/features.md @@ -38,6 +38,7 @@ | SigstoreImageVerification| | | Enabled | Enabled | | TranslateStreamCloseWebsocketRequests| | | Enabled | Enabled | | UpgradeStatus| | | Enabled | Enabled | +| VSphereDriverConfiguration| | | Enabled | Enabled | | ValidatingAdmissionPolicy| | | Enabled | Enabled | | VolumeGroupSnapshot| | | Enabled | Enabled | | ExternalOIDC| Enabled | | Enabled | Enabled | diff --git a/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go b/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go index 0156d6df325d..349c8d461d5b 100644 --- a/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go +++ b/vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go @@ -281,6 +281,35 @@ type VSphereCSIDriverConfigSpec struct { // will be rejected. // +optional TopologyCategories []string `json:"topologyCategories,omitempty"` + + // globalMaxSnapshotsPerBlockVolume is a global configuration parameter that applies to volumes on all kinds of + // datastores. If omitted, the platform chooses a default, which is subject to change over time, currently that default is 3. + // Snapshots can not be disabled using this parameter. + // Increasing number of snapshots above 3 can have negative impact on performance, for more details see: https://kb.vmware.com/s/article/1025279 + // Volume snapshot documentation: https://docs.vmware.com/en/VMware-vSphere-Container-Storage-Plug-in/3.0/vmware-vsphere-csp-getting-started/GUID-E0B41C69-7EEB-450F-A73D-5FD2FF39E891.html + // +kubebuilder:validation:Minimum=1 + // +kubebuilder:validation:Maximum=32 + // +openshift:enable:FeatureGate=VSphereDriverConfiguration + // +optional + GlobalMaxSnapshotsPerBlockVolume *uint32 `json:"globalMaxSnapshotsPerBlockVolume,omitempty"` + + // granularMaxSnapshotsPerBlockVolumeInVSAN is a granular configuration parameter on vSAN datastore only. It + // overrides GlobalMaxSnapshotsPerBlockVolume if set, while it falls back to the global constraint if unset. + // Snapshots for VSAN can not be disabled using this parameter. + // +kubebuilder:validation:Minimum=1 + // +kubebuilder:validation:Maximum=32 + // +openshift:enable:FeatureGate=VSphereDriverConfiguration + // +optional + GranularMaxSnapshotsPerBlockVolumeInVSAN *uint32 `json:"granularMaxSnapshotsPerBlockVolumeInVSAN,omitempty"` + + // granularMaxSnapshotsPerBlockVolumeInVVOL is a granular configuration parameter on Virtual Volumes datastore only. + // It overrides GlobalMaxSnapshotsPerBlockVolume if set, while it falls back to the global constraint if unset. + // Snapshots for VVOL can not be disabled using this parameter. + // +kubebuilder:validation:Minimum=1 + // +kubebuilder:validation:Maximum=32 + // +openshift:enable:FeatureGate=VSphereDriverConfiguration + // +optional + GranularMaxSnapshotsPerBlockVolumeInVVOL *uint32 `json:"granularMaxSnapshotsPerBlockVolumeInVVOL,omitempty"` } // ClusterCSIDriverStatus is the observed status of CSI driver operator diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go index 3df3ef544c20..d41982f2a268 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go @@ -5011,6 +5011,21 @@ func (in *VSphereCSIDriverConfigSpec) DeepCopyInto(out *VSphereCSIDriverConfigSp *out = make([]string, len(*in)) copy(*out, *in) } + if in.GlobalMaxSnapshotsPerBlockVolume != nil { + in, out := &in.GlobalMaxSnapshotsPerBlockVolume, &out.GlobalMaxSnapshotsPerBlockVolume + *out = new(uint32) + **out = **in + } + if in.GranularMaxSnapshotsPerBlockVolumeInVSAN != nil { + in, out := &in.GranularMaxSnapshotsPerBlockVolumeInVSAN, &out.GranularMaxSnapshotsPerBlockVolumeInVSAN + *out = new(uint32) + **out = **in + } + if in.GranularMaxSnapshotsPerBlockVolumeInVVOL != nil { + in, out := &in.GranularMaxSnapshotsPerBlockVolumeInVVOL, &out.GranularMaxSnapshotsPerBlockVolumeInVVOL + *out = new(uint32) + **out = **in + } return } diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml index 82fb98c86c4d..22992a02a040 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml @@ -68,7 +68,8 @@ clustercsidrivers.operator.openshift.io: CRDName: clustercsidrivers.operator.openshift.io Capability: "" Category: "" - FeatureGates: [] + FeatureGates: + - VSphereDriverConfiguration FilenameOperatorName: csi-driver FilenameOperatorOrdering: "01" FilenameRunLevel: "0000_90" diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go index 0743b412fec0..95017ec934c7 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go @@ -501,8 +501,11 @@ func (IBMCloudCSIDriverConfigSpec) SwaggerDoc() map[string]string { } var map_VSphereCSIDriverConfigSpec = map[string]string{ - "": "VSphereCSIDriverConfigSpec defines properties that can be configured for vsphere CSI driver.", - "topologyCategories": "topologyCategories indicates tag categories with which vcenter resources such as hostcluster or datacenter were tagged with. If cluster Infrastructure object has a topology, values specified in Infrastructure object will be used and modifications to topologyCategories will be rejected.", + "": "VSphereCSIDriverConfigSpec defines properties that can be configured for vsphere CSI driver.", + "topologyCategories": "topologyCategories indicates tag categories with which vcenter resources such as hostcluster or datacenter were tagged with. If cluster Infrastructure object has a topology, values specified in Infrastructure object will be used and modifications to topologyCategories will be rejected.", + "globalMaxSnapshotsPerBlockVolume": "globalMaxSnapshotsPerBlockVolume is a global configuration parameter that applies to volumes on all kinds of datastores. If omitted, the platform chooses a default, which is subject to change over time, currently that default is 3. Snapshots can not be disabled using this parameter. Increasing number of snapshots above 3 can have negative impact on performance, for more details see: https://kb.vmware.com/s/article/1025279 Volume snapshot documentation: https://docs.vmware.com/en/VMware-vSphere-Container-Storage-Plug-in/3.0/vmware-vsphere-csp-getting-started/GUID-E0B41C69-7EEB-450F-A73D-5FD2FF39E891.html", + "granularMaxSnapshotsPerBlockVolumeInVSAN": "granularMaxSnapshotsPerBlockVolumeInVSAN is a granular configuration parameter on vSAN datastore only. It overrides GlobalMaxSnapshotsPerBlockVolume if set, while it falls back to the global constraint if unset. Snapshots for VSAN can not be disabled using this parameter.", + "granularMaxSnapshotsPerBlockVolumeInVVOL": "granularMaxSnapshotsPerBlockVolumeInVVOL is a granular configuration parameter on Virtual Volumes datastore only. It overrides GlobalMaxSnapshotsPerBlockVolume if set, while it falls back to the global constraint if unset. Snapshots for VVOL can not be disabled using this parameter.", } func (VSphereCSIDriverConfigSpec) SwaggerDoc() map[string]string { diff --git a/vendor/modules.txt b/vendor/modules.txt index a2fb2ba3842f..1b70b23913e5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -768,7 +768,7 @@ github.com/opencontainers/runtime-spec/specs-go github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label github.com/opencontainers/selinux/pkg/pwalkdir -# github.com/openshift/api v0.0.0-20240410141538-3c0461467316 +# github.com/openshift/api v0.0.0-20240415140253-c0feb35ae9fb ## explicit; go 1.21 github.com/openshift/api github.com/openshift/api/annotations