diff --git a/pkg/model/openstackmodel/servergroup.go b/pkg/model/openstackmodel/servergroup.go index 849c3b1653685..a920d9870f1bf 100644 --- a/pkg/model/openstackmodel/servergroup.go +++ b/pkg/model/openstackmodel/servergroup.go @@ -218,11 +218,17 @@ func (b *ServerGroupModelBuilder) Build(c *fi.ModelBuilderContext) error { var masters []*openstacktasks.ServerGroup for _, ig := range b.InstanceGroups { klog.V(2).Infof("Found instance group with name %s and role %v.", ig.Name, ig.Spec.Role) + affinityPolicies := []string{} + if v, ok := ig.ObjectMeta.Annotations[openstack.OS_ANNOTATION+openstack.SERVER_GROUP_AFFINITY]; ok { + affinityPolicies = append(affinityPolicies, v) + } else { + affinityPolicies = append(affinityPolicies, "anti-affinity") + } sgTask := &openstacktasks.ServerGroup{ Name: s(fmt.Sprintf("%s-%s", clusterName, ig.Name)), ClusterName: s(clusterName), IGName: s(ig.Name), - Policies: []string{"anti-affinity"}, + Policies: affinityPolicies, Lifecycle: b.Lifecycle, MaxSize: ig.Spec.MaxSize, } diff --git a/pkg/model/openstackmodel/servergroup_test.go b/pkg/model/openstackmodel/servergroup_test.go index 33828351ce500..57547f427d7e0 100644 --- a/pkg/model/openstackmodel/servergroup_test.go +++ b/pkg/model/openstackmodel/servergroup_test.go @@ -948,6 +948,45 @@ func getServerGroupModelBuilderTestInput() []serverGroupModelBuilderTestInput { }, }, }, + { + desc: "configures server group affinity with annotations", + cluster: &kops.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster", + }, + Spec: kops.ClusterSpec{ + MasterPublicName: "master-public-name", + CloudConfig: &kops.CloudConfiguration{ + Openstack: &kops.OpenstackConfiguration{}, + }, + Subnets: []kops.ClusterSubnetSpec{ + { + Name: "subnet", + Region: "region", + }, + }, + }, + }, + instanceGroups: []*kops.InstanceGroup{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "node", + Annotations: map[string]string{ + "openstack.kops.io/serverGroupAffinity": "soft-anti-affinity", + }, + }, + Spec: kops.InstanceGroupSpec{ + Role: kops.InstanceGroupRoleNode, + Image: "image-node", + MinSize: i32(1), + MaxSize: i32(1), + MachineType: "blc.2-4", + Subnets: []string{"subnet"}, + Zones: []string{"zone-1"}, + }, + }, + }, + }, } } diff --git a/pkg/model/openstackmodel/tests/servergroup/configures-server-group-affinity-with-annotations.yaml b/pkg/model/openstackmodel/tests/servergroup/configures-server-group-affinity-with-annotations.yaml new file mode 100644 index 0000000000000..160fd60441180 --- /dev/null +++ b/pkg/model/openstackmodel/tests/servergroup/configures-server-group-affinity-with-annotations.yaml @@ -0,0 +1,111 @@ +Name: node +--- +AvailabilityZone: zone-1 +Flavor: blc.2-4 +FloatingIP: null +ForAPIServer: false +GroupName: node +ID: null +Image: image-node +Lifecycle: null +Metadata: + KopsInstanceGroup: node + KopsName: node-1-cluster + KopsNetwork: cluster + KopsRole: Node + KubernetesCluster: cluster + cluster_generation: "0" + ig_generation: "0" + k8s: cluster + k8s.io_cluster-autoscaler_node-template_label_kubernetes.io_role: node + k8s.io_cluster-autoscaler_node-template_label_node-role.kubernetes.io_node: "" + k8s.io_role_node: "1" + kops.k8s.io_instancegroup: node +Name: node-1-cluster +Port: + AdditionalSecurityGroups: null + ID: null + Lifecycle: Sync + Name: port-node-1-cluster + Network: + AvailabilityZoneHints: null + ID: null + Lifecycle: null + Name: cluster + Tag: null + SecurityGroups: + - Description: null + ID: null + Lifecycle: null + Name: nodes.cluster + RemoveExtraRules: null + RemoveGroup: false + Subnets: + - CIDR: null + DNSServers: null + ID: null + Lifecycle: null + Name: subnet.cluster + Network: null + Tag: null + Tag: cluster +Region: region +Role: Node +SSHKey: kubernetes.cluster-ba_d8_85_a0_5b_50_b0_01_e0_b2_b0_ae_5d_f6_7a_d1 +SecurityGroups: null +ServerGroup: + ClusterName: cluster + ID: null + IGName: node + Lifecycle: Sync + MaxSize: 1 + Name: cluster-node + Policies: + - soft-anti-affinity +UserData: + task: + Name: node +--- +Lifecycle: null +Name: ca +Signer: null +alternateNames: null +oldFormat: false +subject: cn=kubernetes +type: ca +--- +AdditionalSecurityGroups: null +ID: null +Lifecycle: Sync +Name: port-node-1-cluster +Network: + AvailabilityZoneHints: null + ID: null + Lifecycle: null + Name: cluster + Tag: null +SecurityGroups: +- Description: null + ID: null + Lifecycle: null + Name: nodes.cluster + RemoveExtraRules: null + RemoveGroup: false +Subnets: +- CIDR: null + DNSServers: null + ID: null + Lifecycle: null + Name: subnet.cluster + Network: null + Tag: null +Tag: cluster +--- +ClusterName: cluster +ID: null +IGName: node +Lifecycle: Sync +MaxSize: 1 +Name: cluster-node +Policies: +- soft-anti-affinity diff --git a/upup/pkg/fi/cloudup/openstack/instance.go b/upup/pkg/fi/cloudup/openstack/instance.go index 259a9706cde23..4c06761730c5f 100644 --- a/upup/pkg/fi/cloudup/openstack/instance.go +++ b/upup/pkg/fi/cloudup/openstack/instance.go @@ -39,6 +39,7 @@ const ( OS_ANNOTATION = "openstack.kops.io/" BOOT_FROM_VOLUME = "osVolumeBoot" BOOT_VOLUME_SIZE = "osVolumeSize" + SERVER_GROUP_AFFINITY = "serverGroupAffinity" ) // floatingBackoff is the backoff strategy for listing openstack floatingips