diff --git a/drivers/storage/portworx/deployment.go b/drivers/storage/portworx/deployment.go index 6d90b0ef9..069276687 100644 --- a/drivers/storage/portworx/deployment.go +++ b/drivers/storage/portworx/deployment.go @@ -242,6 +242,10 @@ func (p *portworx) GetKVDBPodSpec( NodeName: nodeName, } + if len(cluster.Spec.Kvdb.TopologySpreadConstraints) > 0 { + podSpec.TopologySpreadConstraints = cluster.Spec.Kvdb.TopologySpreadConstraints + } + if t.cluster.Spec.Placement != nil { if len(t.cluster.Spec.Placement.Tolerations) > 0 { podSpec.Tolerations = make([]v1.Toleration, 0) diff --git a/drivers/storage/portworx/deployment_test.go b/drivers/storage/portworx/deployment_test.go index 6f5bf6590..71a807d21 100644 --- a/drivers/storage/portworx/deployment_test.go +++ b/drivers/storage/portworx/deployment_test.go @@ -4700,6 +4700,82 @@ func TestPodSpecWithClusterIDOverwritten(t *testing.T) { assert.ElementsMatch(t, expectedArgs, actual.Containers[0].Args) } +func TestPodSpecWithKvdbTopologySpreadConstraints(t *testing.T) { + coreops.SetInstance(coreops.New(fakek8sclient.NewSimpleClientset())) + nodeName := "testNode" + + cluster := &corev1.StorageCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "px-cluster", + Namespace: "kube-system", + }, + Spec: corev1.StorageClusterSpec{ + Image: "portworx/oci-monitor:2.0.3.4", + Placement: &corev1.PlacementSpec{ + NodeAffinity: &v1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &v1.NodeSelector{ + NodeSelectorTerms: []v1.NodeSelectorTerm{ + { + MatchExpressions: []v1.NodeSelectorRequirement{ + { + Key: "px/enabled", + Operator: v1.NodeSelectorOpNotIn, + Values: []string{"false"}, + }, + { + Key: "kubernetes.io/os", + Operator: v1.NodeSelectorOpIn, + Values: []string{"linux"}, + }, + { + Key: "node-role.kubernetes.io/master", + Operator: v1.NodeSelectorOpDoesNotExist, + }, + }, + }, + }, + }, + }, + }, + Kvdb: &corev1.KvdbSpec{ + Internal: true, + TopologySpreadConstraints: []v1.TopologySpreadConstraint{{ + TopologyKey: "kubernetes.io/zone", + MaxSkew: 1, + WhenUnsatisfiable: v1.DoNotSchedule, + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "kvdb": "true", + }, + }, + }}, + }, + SecretsProvider: stringPtr("k8s"), + CommonConfig: corev1.CommonConfig{ + Storage: &corev1.StorageSpec{ + UseAll: boolPtr(true), + ForceUseDisks: boolPtr(true), + }, + Env: []v1.EnvVar{ + { + Name: "TEST_KEY", + Value: "TEST_VALUE", + }, + }, + RuntimeOpts: map[string]string{ + "op1": "10", + }, + }, + }, + } + + driver := portworx{} + + actual, err := driver.GetKVDBPodSpec(cluster, nodeName) + require.NoError(t, err) + assert.Len(t, actual.TopologySpreadConstraints, 1) +} + func getExpectedPodSpecFromDaemonset(t *testing.T, fileName string) *v1.PodSpec { json, err := os.ReadFile(fileName) assert.NoError(t, err) diff --git a/pkg/apis/core/v1/storagecluster.go b/pkg/apis/core/v1/storagecluster.go index 48934f14d..33813ab91 100644 --- a/pkg/apis/core/v1/storagecluster.go +++ b/pkg/apis/core/v1/storagecluster.go @@ -366,6 +366,10 @@ type KvdbSpec struct { // to authenticate with the kvdb. It could have the username/password // for basic auth, certificate information or ACL token. AuthSecret string `json:"authSecret,omitempty"` + + // TopologySpreadConstraints enable the kvdb cluster to be distributed + // based on a topology spread constraint spec + TopologySpreadConstraints []v1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"` } // NetworkSpec contains network information diff --git a/pkg/apis/core/v1/zz_generated.deepcopy.go b/pkg/apis/core/v1/zz_generated.deepcopy.go index 165aea9cc..658edb1ff 100644 --- a/pkg/apis/core/v1/zz_generated.deepcopy.go +++ b/pkg/apis/core/v1/zz_generated.deepcopy.go @@ -1,23 +1,7 @@ //go:build !ignore_autogenerated // +build !ignore_autogenerated -/* -Copyright 2019 Openstorage.org - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS 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. +// Code generated by controller-gen. DO NOT EDIT. package v1 @@ -26,13 +10,12 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" - intstr "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/apimachinery/pkg/util/intstr" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AlertManagerSpec) DeepCopyInto(out *AlertManagerSpec) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlertManagerSpec. @@ -63,7 +46,6 @@ func (in *AuthSpec) DeepCopyInto(out *AuthSpec) { *out = new(SelfSignedSpec) (*in).DeepCopyInto(*out) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthSpec. @@ -117,7 +99,6 @@ func (in *AutopilotSpec) DeepCopyInto(out *AutopilotSpec) { *out = new(corev1.ResourceRequirements) (*in).DeepCopyInto(*out) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutopilotSpec. @@ -143,7 +124,6 @@ func (in *CSISpec) DeepCopyInto(out *CSISpec) { *out = new(CSITopologySpec) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CSISpec. @@ -159,7 +139,6 @@ func (in *CSISpec) DeepCopy() *CSISpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CSITopologySpec) DeepCopyInto(out *CSITopologySpec) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CSITopologySpec. @@ -185,7 +164,6 @@ func (in *CertLocation) DeepCopyInto(out *CertLocation) { *out = new(SecretRef) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CertLocation. @@ -201,7 +179,6 @@ func (in *CertLocation) DeepCopy() *CertLocation { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CheckResult) DeepCopyInto(out *CheckResult) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CheckResult. @@ -224,7 +201,6 @@ func (in *CloudStorageCapacitySpec) DeepCopyInto(out *CloudStorageCapacitySpec) (*out)[key] = val } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudStorageCapacitySpec. @@ -269,7 +245,6 @@ func (in *CloudStorageCommon) DeepCopyInto(out *CloudStorageCommon) { *out = new(uint32) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudStorageCommon. @@ -286,7 +261,6 @@ func (in *CloudStorageCommon) DeepCopy() *CloudStorageCommon { func (in *CloudStorageNodeSpec) DeepCopyInto(out *CloudStorageNodeSpec) { *out = *in in.CloudStorageCommon.DeepCopyInto(&out.CloudStorageCommon) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudStorageNodeSpec. @@ -325,7 +299,6 @@ func (in *CloudStorageSpec) DeepCopyInto(out *CloudStorageSpec) { *out = new(uint32) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudStorageSpec. @@ -342,7 +315,6 @@ func (in *CloudStorageSpec) DeepCopy() *CloudStorageSpec { func (in *ClusterCondition) DeepCopyInto(out *ClusterCondition) { *out = *in in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCondition. @@ -382,7 +354,6 @@ func (in *CommonConfig) DeepCopyInto(out *CommonConfig) { (*out)[key] = val } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonConfig. @@ -398,7 +369,6 @@ func (in *CommonConfig) DeepCopy() *CommonConfig { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ComponentImages) DeepCopyInto(out *ComponentImages) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentImages. @@ -421,7 +391,6 @@ func (in *DataProviderSpec) DeepCopyInto(out *DataProviderSpec) { (*out)[key] = val } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataProviderSpec. @@ -434,10 +403,29 @@ func (in *DataProviderSpec) DeepCopy() *DataProviderSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Disruption) DeepCopyInto(out *Disruption) { + *out = *in + if in.Allow != nil { + in, out := &in.Allow, &out.Allow + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Disruption. +func (in *Disruption) DeepCopy() *Disruption { + if in == nil { + return nil + } + out := new(Disruption) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Geography) DeepCopyInto(out *Geography) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Geography. @@ -460,7 +448,6 @@ func (in *GitOpsSpec) DeepCopyInto(out *GitOpsSpec) { (*out)[key] = val } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitOpsSpec. @@ -476,7 +463,6 @@ func (in *GitOpsSpec) DeepCopy() *GitOpsSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GrafanaSpec) DeepCopyInto(out *GrafanaSpec) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrafanaSpec. @@ -497,7 +483,13 @@ func (in *KvdbSpec) DeepCopyInto(out *KvdbSpec) { *out = make([]string, len(*in)) copy(*out, *in) } - return + 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]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KvdbSpec. @@ -547,7 +539,6 @@ func (in *Metadata) DeepCopyInto(out *Metadata) { (*out)[key] = outVal } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Metadata. @@ -583,7 +574,6 @@ func (in *MonitoringSpec) DeepCopyInto(out *MonitoringSpec) { *out = new(TelemetrySpec) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MonitoringSpec. @@ -609,7 +599,6 @@ func (in *NetworkSpec) DeepCopyInto(out *NetworkSpec) { *out = new(string) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkSpec. @@ -625,7 +614,6 @@ func (in *NetworkSpec) DeepCopy() *NetworkSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NetworkStatus) DeepCopyInto(out *NetworkStatus) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkStatus. @@ -651,7 +639,6 @@ func (in *NodeAttributes) DeepCopyInto(out *NodeAttributes) { *out = new(bool) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeAttributes. @@ -668,7 +655,6 @@ func (in *NodeAttributes) DeepCopy() *NodeAttributes { func (in *NodeCondition) DeepCopyInto(out *NodeCondition) { *out = *in in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeCondition. @@ -689,7 +675,6 @@ func (in *NodeSelector) DeepCopyInto(out *NodeSelector) { *out = new(metav1.LabelSelector) (*in).DeepCopyInto(*out) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeSelector. @@ -712,7 +697,6 @@ func (in *NodeSpec) DeepCopyInto(out *NodeSpec) { (*in).DeepCopyInto(*out) } in.CommonConfig.DeepCopyInto(&out.CommonConfig) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeSpec. @@ -760,7 +744,6 @@ func (in *NodeStatus) DeepCopyInto(out *NodeStatus) { *out = new(NodeAttributes) (*in).DeepCopyInto(*out) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeStatus. @@ -788,7 +771,6 @@ func (in *PlacementSpec) DeepCopyInto(out *PlacementSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PlacementSpec. @@ -839,7 +821,6 @@ func (in *PrometheusSpec) DeepCopyInto(out *PrometheusSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PrometheusSpec. @@ -855,7 +836,6 @@ func (in *PrometheusSpec) DeepCopy() *PrometheusSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PxRepoSpec) DeepCopyInto(out *PxRepoSpec) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PxRepoSpec. @@ -876,7 +856,7 @@ func (in *RollingUpdateStorageCluster) DeepCopyInto(out *RollingUpdateStorageClu *out = new(intstr.IntOrString) **out = **in } - return + in.Disruption.DeepCopyInto(&out.Disruption) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RollingUpdateStorageCluster. @@ -892,7 +872,6 @@ func (in *RollingUpdateStorageCluster) DeepCopy() *RollingUpdateStorageCluster { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretRef) DeepCopyInto(out *SecretRef) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretRef. @@ -918,7 +897,6 @@ func (in *SecuritySpec) DeepCopyInto(out *SecuritySpec) { *out = new(TLSSpec) (*in).DeepCopyInto(*out) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecuritySpec. @@ -949,7 +927,6 @@ func (in *SelfSignedSpec) DeepCopyInto(out *SelfSignedSpec) { *out = new(string) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SelfSignedSpec. @@ -965,7 +942,6 @@ func (in *SelfSignedSpec) DeepCopy() *SelfSignedSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Storage) DeepCopyInto(out *Storage) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Storage. @@ -985,7 +961,6 @@ func (in *StorageCluster) DeepCopyInto(out *StorageCluster) { 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 StorageCluster. @@ -1009,7 +984,6 @@ func (in *StorageCluster) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *StorageClusterDeleteStrategy) DeepCopyInto(out *StorageClusterDeleteStrategy) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageClusterDeleteStrategy. @@ -1034,7 +1008,6 @@ func (in *StorageClusterList) DeepCopyInto(out *StorageClusterList) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageClusterList. @@ -1171,7 +1144,6 @@ func (in *StorageClusterSpec) DeepCopyInto(out *StorageClusterSpec) { *out = new(CSISpec) (*in).DeepCopyInto(*out) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageClusterSpec. @@ -1205,7 +1177,6 @@ func (in *StorageClusterStatus) DeepCopyInto(out *StorageClusterStatus) { *out = new(ComponentImages) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageClusterStatus. @@ -1226,7 +1197,6 @@ func (in *StorageClusterUpdateStrategy) DeepCopyInto(out *StorageClusterUpdateSt *out = new(RollingUpdateStorageCluster) (*in).DeepCopyInto(*out) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageClusterUpdateStrategy. @@ -1246,7 +1216,6 @@ func (in *StorageNode) DeepCopyInto(out *StorageNode) { 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 StorageNode. @@ -1277,7 +1246,6 @@ func (in *StorageNodeCloudDriveConfig) DeepCopyInto(out *StorageNodeCloudDriveCo (*out)[key] = val } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageNodeCloudDriveConfig. @@ -1300,7 +1268,6 @@ func (in *StorageNodeCloudDriveConfigs) DeepCopyInto(out *StorageNodeCloudDriveC (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageNodeCloudDriveConfigs. @@ -1325,7 +1292,6 @@ func (in *StorageNodeList) DeepCopyInto(out *StorageNodeList) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageNodeList. @@ -1350,7 +1316,6 @@ func (in *StorageNodeList) DeepCopyObject() runtime.Object { func (in *StorageNodeSpec) DeepCopyInto(out *StorageNodeSpec) { *out = *in in.CloudStorage.DeepCopyInto(&out.CloudStorage) - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageNodeSpec. @@ -1414,7 +1379,6 @@ func (in *StorageSpec) DeepCopyInto(out *StorageSpec) { *out = new(string) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageSpec. @@ -1432,7 +1396,6 @@ func (in *StorageStatus) DeepCopyInto(out *StorageStatus) { *out = *in out.TotalSize = in.TotalSize.DeepCopy() out.UsedSize = in.UsedSize.DeepCopy() - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageStatus. @@ -1479,7 +1442,6 @@ func (in *StorkSpec) DeepCopyInto(out *StorkSpec) { *out = new(corev1.ResourceRequirements) (*in).DeepCopyInto(*out) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorkSpec. @@ -1515,7 +1477,6 @@ func (in *TLSSpec) DeepCopyInto(out *TLSSpec) { *out = new(CertLocation) (*in).DeepCopyInto(*out) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSSpec. @@ -1531,7 +1492,6 @@ func (in *TLSSpec) DeepCopy() *TLSSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TelemetrySpec) DeepCopyInto(out *TelemetrySpec) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TelemetrySpec. @@ -1554,7 +1514,6 @@ func (in *UserInterfaceSpec) DeepCopyInto(out *UserInterfaceSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserInterfaceSpec. @@ -1576,7 +1535,6 @@ func (in *VolumeSpec) DeepCopyInto(out *VolumeSpec) { *out = new(corev1.MountPropagationMode) **out = **in } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeSpec.