From 498615e10cdf73f8d8c3c0f88f19aed93e763178 Mon Sep 17 00:00:00 2001 From: "Derek Lemon -T (delemon - AEROTEK INC at Cisco)" Date: Thu, 31 Jan 2019 14:09:39 -0700 Subject: [PATCH] Openstack Floating IP Deletion --- pkg/resources/openstack/floatingip.go | 76 +++++++++++++++++++++ pkg/resources/openstack/instances.go | 8 +++ pkg/resources/openstack/network.go | 8 +++ upup/pkg/fi/cloudup/openstack/cloud.go | 3 + upup/pkg/fi/cloudup/openstack/floatingip.go | 38 ++++++++++- 5 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 pkg/resources/openstack/floatingip.go diff --git a/pkg/resources/openstack/floatingip.go b/pkg/resources/openstack/floatingip.go new file mode 100644 index 0000000000..1043168b49 --- /dev/null +++ b/pkg/resources/openstack/floatingip.go @@ -0,0 +1,76 @@ +/* +Copyright 2019 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. +*/ + +package openstack + +import ( + l3floatingip "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" + "k8s.io/kops/pkg/resources" + "k8s.io/kops/upup/pkg/fi" + "k8s.io/kops/upup/pkg/fi/cloudup/openstack" +) + +const ( + typeFloatingIP = "FloatingIP" +) + +func DeleteFloatingIP(cloud fi.Cloud, r *resources.Resource) error { + return cloud.(openstack.OpenstackCloud).DeleteFloatingIP(r.ID) +} + +func DeleteL3FloatingIP(cloud fi.Cloud, r *resources.Resource) error { + return cloud.(openstack.OpenstackCloud).DeleteL3FloatingIP(r.ID) +} + +func (os *clusterDiscoveryOS) listL3FloatingIPs(routerID string) ([]*resources.Resource, error) { + var resourceTrackers []*resources.Resource + l3floatingIPs, err := os.osCloud.ListL3FloatingIPs(l3floatingip.ListOpts{}) + if err != nil { + return resourceTrackers, err + } + for _, floatingIP := range l3floatingIPs { + if floatingIP.RouterID == routerID { + resourceTracker := &resources.Resource{ + Name: floatingIP.FloatingIP, + ID: floatingIP.ID, + Type: typeFloatingIP, + Deleter: DeleteL3FloatingIP, + } + resourceTrackers = append(resourceTrackers, resourceTracker) + } + } + return resourceTrackers, nil +} + +func (os *clusterDiscoveryOS) listFloatingIPs(instanceID string) ([]*resources.Resource, error) { + var resourceTrackers []*resources.Resource + floatingIPs, err := os.osCloud.ListFloatingIPs() + if err != nil { + return resourceTrackers, err + } + for _, floatingIP := range floatingIPs { + if floatingIP.InstanceID == instanceID { + resourceTracker := &resources.Resource{ + Name: floatingIP.IP, + ID: floatingIP.ID, + Type: typeFloatingIP, + Deleter: DeleteFloatingIP, + } + resourceTrackers = append(resourceTrackers, resourceTracker) + } + } + return resourceTrackers, nil +} diff --git a/pkg/resources/openstack/instances.go b/pkg/resources/openstack/instances.go index 88673d6bd9..daa94ff1a6 100644 --- a/pkg/resources/openstack/instances.go +++ b/pkg/resources/openstack/instances.go @@ -38,6 +38,14 @@ func (os *clusterDiscoveryOS) ListInstances() ([]*resources.Resource, error) { } for _, instance := range instances { + + // Clean up any bound floating IP's + floatingIPs, err := os.listFloatingIPs(instance.ID) + if err != nil { + return resourceTrackers, err + } + resourceTrackers = append(resourceTrackers, floatingIPs...) + resourceTracker := &resources.Resource{ Name: instance.Name, ID: instance.ID, diff --git a/pkg/resources/openstack/network.go b/pkg/resources/openstack/network.go index 50bf1539a5..4e5225253f 100644 --- a/pkg/resources/openstack/network.go +++ b/pkg/resources/openstack/network.go @@ -55,6 +55,14 @@ func (os *clusterDiscoveryOS) ListNetwork() ([]*resources.Resource, error) { return resourceTrackers, err } for _, router := range routers { + + // Get the floating IP's associated to this router + floatingIPs, err := os.listL3FloatingIPs(router.ID) + if err != nil { + return resourceTrackers, err + } + resourceTrackers = append(resourceTrackers, floatingIPs...) + resourceTracker := &resources.Resource{ Name: router.Name, ID: router.ID, diff --git a/upup/pkg/fi/cloudup/openstack/cloud.go b/upup/pkg/fi/cloudup/openstack/cloud.go index 7071905b5e..ea36413b87 100644 --- a/upup/pkg/fi/cloudup/openstack/cloud.go +++ b/upup/pkg/fi/cloudup/openstack/cloud.go @@ -252,10 +252,13 @@ type OpenstackCloud interface { GetFloatingIP(id string) (fip *floatingips.FloatingIP, err error) AssociateFloatingIPToInstance(serverID string, opts floatingips.AssociateOpts) (err error) + ListFloatingIPs() (fips []floatingips.FloatingIP, err error) ListL3FloatingIPs(opts l3floatingip.ListOpts) (fips []l3floatingip.FloatingIP, err error) CreateFloatingIP(opts floatingips.CreateOpts) (*floatingips.FloatingIP, error) CreateL3FloatingIP(opts l3floatingip.CreateOpts) (fip *l3floatingip.FloatingIP, err error) + DeleteFloatingIP(id string) error + DeleteL3FloatingIP(id string) error } type openstackCloud struct { diff --git a/upup/pkg/fi/cloudup/openstack/floatingip.go b/upup/pkg/fi/cloudup/openstack/floatingip.go index 5b2c14ac04..1a59119e91 100644 --- a/upup/pkg/fi/cloudup/openstack/floatingip.go +++ b/upup/pkg/fi/cloudup/openstack/floatingip.go @@ -97,7 +97,7 @@ func (c *openstackCloud) CreateL3FloatingIP(opts l3floatingip.CreateOpts) (fip * func (c *openstackCloud) ListFloatingIPs() (fips []floatingips.FloatingIP, err error) { done, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) { - pages, err := floatingips.List(c.novaClient).AllPages() + pages, err := floatingips.List(c.ComputeClient()).AllPages() if err != nil { return false, fmt.Errorf("Failed to list floating ip: %v", err) } @@ -137,3 +137,39 @@ func (c *openstackCloud) ListL3FloatingIPs(opts l3floatingip.ListOpts) (fips []l } return fips, nil } + +func (c *openstackCloud) DeleteFloatingIP(id string) (err error) { + + done, err := vfs.RetryWithBackoff(writeBackoff, func() (bool, error) { + err = l3floatingip.Delete(c.ComputeClient(), id).ExtractErr() + if err != nil { + return false, fmt.Errorf("Failed to delete floating ip %s: %v", id, err) + } + return true, nil + }) + if !done { + if err == nil { + err = wait.ErrWaitTimeout + } + return err + } + return err +} + +func (c *openstackCloud) DeleteL3FloatingIP(id string) (err error) { + + done, err := vfs.RetryWithBackoff(writeBackoff, func() (bool, error) { + err = l3floatingip.Delete(c.NetworkingClient(), id).ExtractErr() + if err != nil { + return false, fmt.Errorf("Failed to delete L3 floating ip %s: %v", id, err) + } + return true, nil + }) + if !done { + if err == nil { + err = wait.ErrWaitTimeout + } + return err + } + return err +}