From 4b9c46d37423fade201d8b0cd18f8147cc7d7efa Mon Sep 17 00:00:00 2001 From: Hidekazu Nakamura Date: Tue, 24 Mar 2020 01:22:57 +0000 Subject: [PATCH] Delete router/network/subnet --- controllers/openstackcluster_controller.go | 19 +++++++++- pkg/cloud/services/networking/network.go | 30 ++++++++++++++++ pkg/cloud/services/networking/router.go | 41 ++++++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/controllers/openstackcluster_controller.go b/controllers/openstackcluster_controller.go index b5fd3f533d..676032595a 100644 --- a/controllers/openstackcluster_controller.go +++ b/controllers/openstackcluster_controller.go @@ -150,7 +150,23 @@ func (r *OpenStackClusterReconciler) reconcileDelete(ctx context.Context, log lo } } - // TODO(sbueringer) Delete network/subnet/router/... if created by CAPO + if openStackCluster.Status.Network.Router != nil { + log.Info("Deleting router", "name", openStackCluster.Status.Network.Router.Name) + if err := networkingService.DeleteRouter(openStackCluster.Status.Network); err != nil { + return ctrl.Result{}, errors.Errorf("failed to delete router: %v", err) + } + log.Info("OpenStack router deleted successfully") + } + + if openStackCluster.Status.Network != nil { + log.Info("Deleting network", "name", openStackCluster.Status.Network.Name) + if err := networkingService.DeleteNetwork(openStackCluster.Status.Network); err != nil { + return ctrl.Result{}, errors.Errorf("failed to delete network: %v", err) + } + log.Info("OpenStack network deleted successfully") + } + + log.Info("OpenStack cluster deleted successfully") // Cluster is deleted so remove the finalizer. controllerutil.RemoveFinalizer(openStackCluster, infrav1.ClusterFinalizer) @@ -297,6 +313,7 @@ func (r *OpenStackClusterReconciler) reconcileNormal(ctx context.Context, log lo } openStackCluster.Status.Ready = true + log.Info("Reconciled Cluster create successfully") return ctrl.Result{}, nil } diff --git a/pkg/cloud/services/networking/network.go b/pkg/cloud/services/networking/network.go index d145f7f1e3..96c080de54 100644 --- a/pkg/cloud/services/networking/network.go +++ b/pkg/cloud/services/networking/network.go @@ -91,6 +91,22 @@ func (s *Service) ReconcileNetwork(clusterName string, openStackCluster *infrav1 return nil } +func (s *Service) DeleteNetwork(network *infrav1.Network) error { + if network == nil || network.ID == "" { + s.logger.V(4).Info("No need to delete network since no network exists.") + return nil + } + exists, err := s.existsNetwork(network.ID) + if err != nil { + return err + } + if !exists { + s.logger.Info("Skipping network deletion because network doesn't exist", "network", network.ID) + return nil + } + return networks.Delete(s.client, network.ID).ExtractErr() +} + func (s *Service) ReconcileSubnet(clusterName string, openStackCluster *infrav1.OpenStackCluster) error { if openStackCluster.Status.Network == nil || openStackCluster.Status.Network.ID == "" { @@ -188,3 +204,17 @@ func (s *Service) getNetworkByName(networkName string) (networks.Network, error) } return networks.Network{}, errors.New("too many resources") } + +func (s *Service) existsNetwork(networkID string) (bool, error) { + if networkID == "" { + return false, nil + } + network, err := networks.Get(s.client, networkID).Extract() + if err != nil { + return false, err + } + if network == nil { + return false, nil + } + return true, nil +} diff --git a/pkg/cloud/services/networking/router.go b/pkg/cloud/services/networking/router.go index dfb17aac80..d5ce90567b 100644 --- a/pkg/cloud/services/networking/router.go +++ b/pkg/cloud/services/networking/router.go @@ -165,6 +165,33 @@ INTERFACE_LOOP: return nil } +func (s *Service) DeleteRouter(network *infrav1.Network) error { + if network.Router == nil || network.Router.ID == "" { + s.logger.V(4).Info("No need to delete router since no router exists.") + return nil + } + exists, err := s.existsRouter(network.Router.ID) + if err != nil { + return err + } + if !exists { + s.logger.Info("Skipping router deletion because router doesn't exist", "router", network.Router.ID) + return nil + } + if network.Subnet == nil || network.Subnet.ID == "" { + s.logger.V(4).Info("Skipping removing router interface since no subnet exists.") + } else { + _, err = routers.RemoveInterface(s.client, network.Router.ID, routers.RemoveInterfaceOpts{ + SubnetID: network.Subnet.ID, + }).Extract() + if err != nil { + return fmt.Errorf("unable to remove router interface: %v", err) + } + s.logger.V(4).Info("Removed RouterInterface of Router", "id", network.Router.ID) + } + return routers.Delete(s.client, network.Router.ID).ExtractErr() +} + func (s *Service) getRouterInterfaces(routerID string) ([]ports.Port, error) { allPages, err := ports.List(s.client, ports.ListOpts{ DeviceID: routerID, @@ -247,3 +274,17 @@ func GetSubnetsByFilter(networkClient *gophercloud.ServiceClient, opts subnets.L } return snets, nil } + +func (s *Service) existsRouter(routerID string) (bool, error) { + if routerID == "" { + return false, nil + } + router, err := routers.Get(s.client, routerID).Extract() + if err != nil { + return false, err + } + if router == nil { + return false, nil + } + return true, nil +}