diff --git a/cloudmock/openstack/mockcompute/servers.go b/cloudmock/openstack/mockcompute/servers.go index 2a0b21cb8d..bac83ac111 100644 --- a/cloudmock/openstack/mockcompute/servers.go +++ b/cloudmock/openstack/mockcompute/servers.go @@ -153,7 +153,7 @@ func (m *MockClient) listServers(w http.ResponseWriter, vals url.Values) { serverName := strings.Trim(vals.Get("name"), "^$") matched := make([]servers.Server, 0) for _, server := range m.servers { - if server.Name == serverName { + if strings.HasPrefix(server.Name, serverName) { matched = append(matched, server) } } diff --git a/pkg/model/openstackmodel/servergroup.go b/pkg/model/openstackmodel/servergroup.go index 24bd5c8d8f..849c3b1653 100644 --- a/pkg/model/openstackmodel/servergroup.go +++ b/pkg/model/openstackmodel/servergroup.go @@ -100,6 +100,8 @@ func (b *ServerGroupModelBuilder) buildInstances(c *fi.ModelBuilderContext, sg * securityGroups = append(securityGroups, b.LinkToSecurityGroup(b.Cluster.Spec.MasterPublicName)) } + r := strings.NewReplacer("_", "-", ".", "-") + groupName := r.Replace(strings.ToLower(ig.Name)) // In the future, OpenStack will use Machine API to manage groups, // for now create d.InstanceGroups.Spec.MinSize amount of servers for i := int32(0); i < *ig.Spec.MinSize; i++ { @@ -141,8 +143,14 @@ func (b *ServerGroupModelBuilder) buildInstances(c *fi.ModelBuilderContext, sg * } c.AddTask(portTask) + metaWithName := make(map[string]string) + for k, v := range igMeta { + metaWithName[k] = v + } + metaWithName[openstack.TagKopsName] = fi.StringValue(instanceName) instanceTask := &openstacktasks.Instance{ Name: instanceName, + GroupName: s(groupName), Region: fi.String(b.Cluster.Spec.Subnets[0].Region), Flavor: fi.String(ig.Spec.MachineType), Image: fi.String(ig.Spec.Image), @@ -151,7 +159,7 @@ func (b *ServerGroupModelBuilder) buildInstances(c *fi.ModelBuilderContext, sg * Role: fi.String(string(ig.Spec.Role)), Port: portTask, UserData: startupScript, - Metadata: igMeta, + Metadata: metaWithName, SecurityGroups: ig.Spec.AdditionalSecurityGroups, AvailabilityZone: az, } diff --git a/pkg/model/openstackmodel/tests/servergroup/adds-additional-security-groups.yaml b/pkg/model/openstackmodel/tests/servergroup/adds-additional-security-groups.yaml index 273181e305..93e8374456 100644 --- a/pkg/model/openstackmodel/tests/servergroup/adds-additional-security-groups.yaml +++ b/pkg/model/openstackmodel/tests/servergroup/adds-additional-security-groups.yaml @@ -4,11 +4,13 @@ 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 diff --git a/pkg/model/openstackmodel/tests/servergroup/adds-cloud-labels-from-ClusterSpec.yaml b/pkg/model/openstackmodel/tests/servergroup/adds-cloud-labels-from-ClusterSpec.yaml index 22baa76de1..b7a4ea0161 100644 --- a/pkg/model/openstackmodel/tests/servergroup/adds-cloud-labels-from-ClusterSpec.yaml +++ b/pkg/model/openstackmodel/tests/servergroup/adds-cloud-labels-from-ClusterSpec.yaml @@ -4,11 +4,13 @@ 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 diff --git a/pkg/model/openstackmodel/tests/servergroup/adds-cloud-labels-from-InstanceGroupSpec.yaml b/pkg/model/openstackmodel/tests/servergroup/adds-cloud-labels-from-InstanceGroupSpec.yaml index 22baa76de1..b7a4ea0161 100644 --- a/pkg/model/openstackmodel/tests/servergroup/adds-cloud-labels-from-InstanceGroupSpec.yaml +++ b/pkg/model/openstackmodel/tests/servergroup/adds-cloud-labels-from-InstanceGroupSpec.yaml @@ -4,11 +4,13 @@ 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 diff --git a/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-bastion-auto-zone-distribution.yaml b/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-bastion-auto-zone-distribution.yaml index 40d6a414c7..e24db43f1c 100644 --- a/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-bastion-auto-zone-distribution.yaml +++ b/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-bastion-auto-zone-distribution.yaml @@ -54,11 +54,13 @@ FloatingIP: Lifecycle: Sync Name: fip-master-1-cluster ForAPIServer: false +GroupName: master ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: master + KopsName: master-1-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -130,11 +132,13 @@ FloatingIP: Lifecycle: Sync Name: fip-master-2-cluster ForAPIServer: false +GroupName: master ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: master + KopsName: master-2-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -206,11 +210,13 @@ FloatingIP: Lifecycle: Sync Name: fip-master-3-cluster ForAPIServer: false +GroupName: master ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: master + KopsName: master-3-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -282,11 +288,13 @@ FloatingIP: Lifecycle: Sync Name: fip-node-1-cluster ForAPIServer: false +GroupName: node ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: node + KopsName: node-1-cluster KopsNetwork: cluster KopsRole: Node KubernetesCluster: cluster @@ -351,11 +359,13 @@ FloatingIP: Lifecycle: Sync Name: fip-node-2-cluster ForAPIServer: false +GroupName: node ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: node + KopsName: node-2-cluster KopsNetwork: cluster KopsRole: Node KubernetesCluster: cluster @@ -420,11 +430,13 @@ FloatingIP: Lifecycle: Sync Name: fip-node-3-cluster ForAPIServer: false +GroupName: node ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: node + KopsName: node-3-cluster KopsNetwork: cluster KopsRole: Node KubernetesCluster: cluster diff --git a/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-bastion-with-API-loadbalancer.yaml b/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-bastion-with-API-loadbalancer.yaml index 257f7bceb9..d6a7f22881 100644 --- a/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-bastion-with-API-loadbalancer.yaml +++ b/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-bastion-with-API-loadbalancer.yaml @@ -55,11 +55,13 @@ AvailabilityZone: zone-1 Flavor: blc.1-2 FloatingIP: null ForAPIServer: false +GroupName: master-a ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: master-a + KopsName: master-a-1-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -119,11 +121,13 @@ AvailabilityZone: zone-2 Flavor: blc.1-2 FloatingIP: null ForAPIServer: false +GroupName: master-b ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: master-b + KopsName: master-b-1-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -183,11 +187,13 @@ AvailabilityZone: zone-3 Flavor: blc.1-2 FloatingIP: null ForAPIServer: false +GroupName: master-c ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: master-c + KopsName: master-c-1-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -253,11 +259,13 @@ FloatingIP: Lifecycle: Sync Name: fip-node-a-1-cluster ForAPIServer: false +GroupName: node-a ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: node-a + KopsName: node-a-1-cluster KopsNetwork: cluster KopsRole: Node KubernetesCluster: cluster @@ -322,11 +330,13 @@ FloatingIP: Lifecycle: Sync Name: fip-node-b-1-cluster ForAPIServer: false +GroupName: node-b ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: node-b + KopsName: node-b-1-cluster KopsNetwork: cluster KopsRole: Node KubernetesCluster: cluster @@ -391,11 +401,13 @@ FloatingIP: Lifecycle: Sync Name: fip-node-c-1-cluster ForAPIServer: false +GroupName: node-c ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: node-c + KopsName: node-c-1-cluster KopsNetwork: cluster KopsRole: Node KubernetesCluster: cluster diff --git a/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-bastion.yaml b/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-bastion.yaml index c44cc7e869..275b665c54 100644 --- a/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-bastion.yaml +++ b/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-bastion.yaml @@ -62,11 +62,13 @@ FloatingIP: Lifecycle: Sync Name: fip-master-a-1-cluster ForAPIServer: false +GroupName: master-a ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: master-a + KopsName: master-a-1-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -138,11 +140,13 @@ FloatingIP: Lifecycle: Sync Name: fip-master-b-1-cluster ForAPIServer: false +GroupName: master-b ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: master-b + KopsName: master-b-1-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -214,11 +218,13 @@ FloatingIP: Lifecycle: Sync Name: fip-master-c-1-cluster ForAPIServer: false +GroupName: master-c ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: master-c + KopsName: master-c-1-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -290,11 +296,13 @@ FloatingIP: Lifecycle: Sync Name: fip-node-a-1-cluster ForAPIServer: false +GroupName: node-a ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: node-a + KopsName: node-a-1-cluster KopsNetwork: cluster KopsRole: Node KubernetesCluster: cluster @@ -359,11 +367,13 @@ FloatingIP: Lifecycle: Sync Name: fip-node-b-1-cluster ForAPIServer: false +GroupName: node-b ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: node-b + KopsName: node-b-1-cluster KopsNetwork: cluster KopsRole: Node KubernetesCluster: cluster @@ -428,11 +438,13 @@ FloatingIP: Lifecycle: Sync Name: fip-node-c-1-cluster ForAPIServer: false +GroupName: node-c ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: node-c + KopsName: node-c-1-cluster KopsNetwork: cluster KopsRole: Node KubernetesCluster: cluster diff --git a/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-external-router.yaml b/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-external-router.yaml index 4720d5a800..47e4276f36 100644 --- a/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-external-router.yaml +++ b/pkg/model/openstackmodel/tests/servergroup/multizone-setup-3-masters-3-nodes-without-external-router.yaml @@ -14,11 +14,13 @@ AvailabilityZone: zone-1 Flavor: blc.1-2 FloatingIP: null ForAPIServer: false +GroupName: master-a ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: master-a + KopsName: master-a-1-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -84,11 +86,13 @@ AvailabilityZone: zone-2 Flavor: blc.1-2 FloatingIP: null ForAPIServer: false +GroupName: master-b ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: master-b + KopsName: master-b-1-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -154,11 +158,13 @@ AvailabilityZone: zone-3 Flavor: blc.1-2 FloatingIP: null ForAPIServer: false +GroupName: master-c ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: master-c + KopsName: master-c-1-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -224,11 +230,13 @@ AvailabilityZone: zone-1 Flavor: blc.1-2 FloatingIP: null ForAPIServer: false +GroupName: node-a ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: node-a + KopsName: node-a-1-cluster KopsNetwork: cluster KopsRole: Node KubernetesCluster: cluster @@ -287,11 +295,13 @@ AvailabilityZone: zone-2 Flavor: blc.1-2 FloatingIP: null ForAPIServer: false +GroupName: node-b ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: node-b + KopsName: node-b-1-cluster KopsNetwork: cluster KopsRole: Node KubernetesCluster: cluster @@ -350,11 +360,13 @@ AvailabilityZone: zone-3 Flavor: blc.1-2 FloatingIP: null ForAPIServer: false +GroupName: node-c ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: node-c + KopsName: node-c-1-cluster KopsNetwork: cluster KopsRole: Node KubernetesCluster: cluster diff --git a/pkg/model/openstackmodel/tests/servergroup/one-master-one-node-one-bastion-2.yaml b/pkg/model/openstackmodel/tests/servergroup/one-master-one-node-one-bastion-2.yaml index 80301451a9..e6c822bd15 100644 --- a/pkg/model/openstackmodel/tests/servergroup/one-master-one-node-one-bastion-2.yaml +++ b/pkg/model/openstackmodel/tests/servergroup/one-master-one-node-one-bastion-2.yaml @@ -8,11 +8,13 @@ AvailabilityZone: zone-1 Flavor: blc.1-2 FloatingIP: null ForAPIServer: false +GroupName: bastion ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: bastion + KopsName: bastion-1-cluster KopsNetwork: cluster KopsRole: Bastion cluster_generation: "0" @@ -70,11 +72,13 @@ AvailabilityZone: zone-1 Flavor: blc.1-2 FloatingIP: null ForAPIServer: false +GroupName: master ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: master + KopsName: master-1-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -140,11 +144,13 @@ AvailabilityZone: zone-1 Flavor: blc.1-2 FloatingIP: null ForAPIServer: false +GroupName: node ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: node + KopsName: node-1-cluster KopsNetwork: cluster KopsRole: Node KubernetesCluster: cluster diff --git a/pkg/model/openstackmodel/tests/servergroup/one-master-one-node-one-bastion.yaml b/pkg/model/openstackmodel/tests/servergroup/one-master-one-node-one-bastion.yaml index eb36e964c0..dfebda14b5 100644 --- a/pkg/model/openstackmodel/tests/servergroup/one-master-one-node-one-bastion.yaml +++ b/pkg/model/openstackmodel/tests/servergroup/one-master-one-node-one-bastion.yaml @@ -28,11 +28,13 @@ FloatingIP: Lifecycle: Sync Name: fip-bastion-1-cluster ForAPIServer: false +GroupName: bastion ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: bastion + KopsName: bastion-1-cluster KopsNetwork: cluster KopsRole: Bastion cluster_generation: "0" @@ -96,11 +98,13 @@ FloatingIP: Lifecycle: Sync Name: fip-master-1-cluster ForAPIServer: false +GroupName: master ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: master + KopsName: master-1-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -166,11 +170,13 @@ AvailabilityZone: zone-1 Flavor: blc.1-2 FloatingIP: null ForAPIServer: false +GroupName: node ID: null Image: image Lifecycle: null Metadata: KopsInstanceGroup: node + KopsName: node-1-cluster KopsNetwork: cluster KopsRole: Node KubernetesCluster: cluster diff --git a/pkg/model/openstackmodel/tests/servergroup/one-master-one-node-without-bastion-no-public-ip-association.yaml b/pkg/model/openstackmodel/tests/servergroup/one-master-one-node-without-bastion-no-public-ip-association.yaml index 8f77767e8c..67d745bfce 100644 --- a/pkg/model/openstackmodel/tests/servergroup/one-master-one-node-without-bastion-no-public-ip-association.yaml +++ b/pkg/model/openstackmodel/tests/servergroup/one-master-one-node-without-bastion-no-public-ip-association.yaml @@ -6,11 +6,13 @@ AvailabilityZone: zone-1 Flavor: blc.1-2 FloatingIP: null ForAPIServer: false +GroupName: master ID: null Image: image-master Lifecycle: null Metadata: KopsInstanceGroup: master + KopsName: master-1-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -76,11 +78,13 @@ 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 diff --git a/pkg/model/openstackmodel/tests/servergroup/one-master-one-node.yaml b/pkg/model/openstackmodel/tests/servergroup/one-master-one-node.yaml index 000c5d54b4..37fd19f16c 100644 --- a/pkg/model/openstackmodel/tests/servergroup/one-master-one-node.yaml +++ b/pkg/model/openstackmodel/tests/servergroup/one-master-one-node.yaml @@ -26,11 +26,13 @@ FloatingIP: Lifecycle: Sync Name: fip-master-1-cluster ForAPIServer: false +GroupName: master ID: null Image: image-master Lifecycle: null Metadata: KopsInstanceGroup: master + KopsName: master-1-cluster KopsNetwork: cluster KopsRole: Master KubernetesCluster: cluster @@ -102,11 +104,13 @@ FloatingIP: Lifecycle: Sync Name: fip-node-1-cluster ForAPIServer: false +GroupName: node ID: null Image: image-node Lifecycle: null Metadata: KopsInstanceGroup: node + KopsName: node-1-cluster KopsNetwork: cluster KopsRole: Node KubernetesCluster: cluster diff --git a/pkg/model/openstackmodel/tests/servergroup/uses-instance-group-subnet-as-availability-zones-fallback.yaml b/pkg/model/openstackmodel/tests/servergroup/uses-instance-group-subnet-as-availability-zones-fallback.yaml index eeda9516e3..fa82fa331b 100644 --- a/pkg/model/openstackmodel/tests/servergroup/uses-instance-group-subnet-as-availability-zones-fallback.yaml +++ b/pkg/model/openstackmodel/tests/servergroup/uses-instance-group-subnet-as-availability-zones-fallback.yaml @@ -4,11 +4,13 @@ AvailabilityZone: subnet 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 diff --git a/pkg/model/openstackmodel/tests/servergroup/uses-instance-group-zones-as-availability-zones.yaml b/pkg/model/openstackmodel/tests/servergroup/uses-instance-group-zones-as-availability-zones.yaml index 3080daec92..ae5bd57353 100644 --- a/pkg/model/openstackmodel/tests/servergroup/uses-instance-group-zones-as-availability-zones.yaml +++ b/pkg/model/openstackmodel/tests/servergroup/uses-instance-group-zones-as-availability-zones.yaml @@ -4,11 +4,13 @@ AvailabilityZone: zone-a 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 diff --git a/pkg/resources/openstack/floatingip.go b/pkg/resources/openstack/floatingip.go index 799a68fff7..8e6cc5e44d 100644 --- a/pkg/resources/openstack/floatingip.go +++ b/pkg/resources/openstack/floatingip.go @@ -17,6 +17,7 @@ limitations under the License. package openstack import ( + "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" l3floatingip "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" "k8s.io/kops/pkg/resources" "k8s.io/kops/upup/pkg/fi" @@ -55,14 +56,16 @@ func (os *clusterDiscoveryOS) listL3FloatingIPs(routerID string) ([]*resources.R return resourceTrackers, nil } -func (os *clusterDiscoveryOS) listFloatingIPs(instanceID string) ([]*resources.Resource, error) { +func (os *clusterDiscoveryOS) listFloatingIPs(instance servers.Server) ([]*resources.Resource, error) { var resourceTrackers []*resources.Resource - instance, err := os.osCloud.GetInstance(instanceID) - if err != nil { - return resourceTrackers, err + // we can find real instance name from instance name in old format + // however, in new format the real name can be found in metadata + name := instance.Name + if val, ok := instance.Metadata[openstack.TagKopsName]; ok { + name = val } floatingIPs, err := os.osCloud.ListL3FloatingIPs(l3floatingip.ListOpts{ - Description: "fip-" + instance.Name, + Description: "fip-" + name, }) if err != nil { return resourceTrackers, err diff --git a/pkg/resources/openstack/instances.go b/pkg/resources/openstack/instances.go index ab1e1f933a..292cd26806 100644 --- a/pkg/resources/openstack/instances.go +++ b/pkg/resources/openstack/instances.go @@ -38,7 +38,7 @@ func (os *clusterDiscoveryOS) ListInstances() ([]*resources.Resource, error) { val, ok := instance.Metadata["k8s"] if ok && val == os.clusterName { // Clean up any bound floating IP's - floatingIPs, err := os.listFloatingIPs(instance.ID) + floatingIPs, err := os.listFloatingIPs(instance) if err != nil { return resourceTrackers, err } diff --git a/upup/pkg/fi/cloudup/openstack/cloud.go b/upup/pkg/fi/cloudup/openstack/cloud.go index e11ef8181a..1b16d8e3b4 100644 --- a/upup/pkg/fi/cloudup/openstack/cloud.go +++ b/upup/pkg/fi/cloudup/openstack/cloud.go @@ -65,6 +65,7 @@ const ( TagClusterName = "KubernetesCluster" TagRoleMaster = "master" TagKopsNetwork = "KopsNetwork" + TagKopsName = "KopsName" ResourceTypePort = "ports" ResourceTypeNetwork = "networks" ResourceTypeSubnet = "subnets" diff --git a/upup/pkg/fi/cloudup/openstacktasks/instance.go b/upup/pkg/fi/cloudup/openstacktasks/instance.go index f96d8a3921..1ffc297610 100644 --- a/upup/pkg/fi/cloudup/openstacktasks/instance.go +++ b/upup/pkg/fi/cloudup/openstacktasks/instance.go @@ -19,6 +19,7 @@ package openstacktasks import ( "fmt" "strconv" + "strings" l3floatingip "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" "github.com/gophercloud/gophercloud/openstack/networking/v2/ports" @@ -36,6 +37,7 @@ import ( type Instance struct { ID *string Name *string + GroupName *string Port *Port Region *string Flavor *string @@ -118,31 +120,51 @@ func (e *Instance) Find(c *fi.Context) (*Instance, error) { cloud := c.Cloud.(openstack.OpenstackCloud) computeClient := cloud.ComputeClient() serverPage, err := servers.List(computeClient, servers.ListOpts{ - Name: fmt.Sprintf("^%s$", fi.StringValue(e.Name)), + Name: fmt.Sprintf("^%s", fi.StringValue(e.GroupName)), }).AllPages() if err != nil { - return nil, fmt.Errorf("error finding server with name %s: %v", fi.StringValue(e.Name), err) + return nil, fmt.Errorf("error listing servers: %v", err) } serverList, err := servers.ExtractServers(serverPage) if err != nil { return nil, fmt.Errorf("error extracting server page: %v", err) } - if len(serverList) == 0 { + + var filteredList []servers.Server + for _, server := range serverList { + val, ok := server.Metadata["k8s"] + if !ok || val != fi.StringValue(e.ServerGroup.ClusterName) { + continue + } + metadataName := "" + val, ok = server.Metadata[openstack.TagKopsName] + if ok { + metadataName = val + } + // name or metadata tag should match to instance name + // this is needed for backwards compatibility + if server.Name == fi.StringValue(e.Name) || metadataName == fi.StringValue(e.Name) { + filteredList = append(filteredList, server) + } + } + + if filteredList == nil { return nil, nil } - if len(serverList) > 1 { + if len(filteredList) > 1 { return nil, fmt.Errorf("Multiple servers found with name %s", fi.StringValue(e.Name)) } - server := serverList[0] + server := filteredList[0] actual := &Instance{ ID: fi.String(server.ID), - Name: fi.String(server.Name), + Name: e.Name, SSHKey: fi.String(server.KeyName), Lifecycle: e.Lifecycle, Metadata: server.Metadata, Role: fi.String(server.Metadata["KopsRole"]), AvailabilityZone: e.AvailabilityZone, + GroupName: e.GroupName, } ports, err := cloud.ListPorts(ports.ListOpts{ @@ -235,10 +257,30 @@ func (_ *Instance) ShouldCreate(a, e, changes *Instance) (bool, error) { return false, nil } +// generateInstanceName generates name for the instance +// the instance format is [GroupName]-[6 character hash] +func generateInstanceName(e *Instance) (string, error) { + secret, err := fi.CreateSecret() + if err != nil { + return "", err + } + + hash, err := secret.AsString() + if err != nil { + return "", err + } + + return strings.ToLower(fmt.Sprintf("%s-%s", fi.StringValue(e.GroupName), hash[0:6])), nil +} + func (_ *Instance) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, changes *Instance) error { cloud := t.Cloud.(openstack.OpenstackCloud) if a == nil { - klog.V(2).Infof("Creating Instance with name: %q", fi.StringValue(e.Name)) + serverName, err := generateInstanceName(e) + if err != nil { + return err + } + klog.V(2).Infof("Creating Instance with name: %q", serverName) imageName := fi.StringValue(e.Image) image, err := cloud.GetImage(imageName) @@ -253,7 +295,7 @@ func (_ *Instance) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, change } opt := servers.CreateOpts{ - Name: fi.StringValue(e.Name), + Name: serverName, ImageRef: image.ID, FlavorRef: flavor.ID, Networks: []servers.Network{ diff --git a/upup/pkg/fi/cloudup/openstacktasks/servergroup.go b/upup/pkg/fi/cloudup/openstacktasks/servergroup.go index 1bea854921..6431fa36b7 100644 --- a/upup/pkg/fi/cloudup/openstacktasks/servergroup.go +++ b/upup/pkg/fi/cloudup/openstacktasks/servergroup.go @@ -144,13 +144,31 @@ func (_ *ServerGroup) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, cha iName := strings.ToLower(fmt.Sprintf("%s-%d.%s", fi.StringValue(a.IGName), currentLastIndex, fi.StringValue(a.ClusterName))) instanceName := strings.Replace(iName, ".", "-", -1) opts := servers.ListOpts{ - Name: fmt.Sprintf("^%s$", instanceName), + Name: fmt.Sprintf("^%s", fi.StringValue(a.IGName)), } - instances, err := t.Cloud.ListInstances(opts) + allInstances, err := t.Cloud.ListInstances(opts) if err != nil { return fmt.Errorf("error fetching instance list: %v", err) } + instances := []servers.Server{} + for _, server := range allInstances { + val, ok := server.Metadata["k8s"] + if !ok || val != fi.StringValue(a.ClusterName) { + continue + } + metadataName := "" + val, ok = server.Metadata[openstack.TagKopsName] + if ok { + metadataName = val + } + // name or metadata tag should match to instance name + // this is needed for backwards compatibility + if server.Name == instanceName || metadataName == instanceName { + instances = append(instances, server) + } + } + if len(instances) == 1 { klog.V(2).Infof("Openstack task ServerGroup scaling down instance %s", instanceName) err := t.Cloud.DeleteInstanceWithID(instances[0].ID)