Skip to content

Commit

Permalink
Add cleanup for VPC load balancers
Browse files Browse the repository at this point in the history
  • Loading branch information
Amulyam24 committed Jan 19, 2023
1 parent 3e30fa4 commit 95bd75d
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 0 deletions.
3 changes: 3 additions & 0 deletions internal/ibmcloud-janitor/resources/types.go
Expand Up @@ -45,6 +45,7 @@ var PowervsResources = []Resource{

var VpcResources = []Resource{
VPCInstance{},
VPCLoadBalancer{},
VPCNetwork{},
VPCs{},
}
Expand Down Expand Up @@ -74,6 +75,8 @@ type VPC interface {
GetSubnetPublicGateway(options *vpcv1.GetSubnetPublicGatewayOptions) (*vpcv1.PublicGateway, *core.DetailedResponse, error)
DeletePublicGateway(options *vpcv1.DeletePublicGatewayOptions) (*core.DetailedResponse, error)
UnsetSubnetPublicGateway(options *vpcv1.UnsetSubnetPublicGatewayOptions) (*core.DetailedResponse, error)
DeleteLoadBalancer(options *vpcv1.DeleteLoadBalancerOptions) (*core.DetailedResponse, error)
ListLoadBalancers(options *vpcv1.ListLoadBalancersOptions) (*vpcv1.LoadBalancerCollection, *core.DetailedResponse, error)
}

type ServiceIDClient interface {
Expand Down
67 changes: 67 additions & 0 deletions internal/ibmcloud-janitor/resources/util.go
@@ -0,0 +1,67 @@
/*
Copyright 2022 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 resources

import (
"net/url"

"github.com/pkg/errors"
)

// pagingHelper is used while listing resources. It parses and fetches the start token for
// getting the next set of resources if nextURL is returned by func f.
// func f has start as a parameter and returns the following:
// isDone bool - true denotes that iterating is not needed as there is no next set of resources
// nextURL string - denotes a URL for a page of resources which is parsed for fetching start token for next iteration
// e error - will break and return error if e is not nil
func pagingHelper(f func(string) (bool, string, error)) (err error) {
start := ""

getStartToken := func(nextURL string) (string, error) {
url, err := url.Parse(nextURL)
if err != nil || url == nil {
return "", errors.Wrapf(err, "failed to parse next url for getting next resources")
}

start := url.Query().Get("start")
return start, nil
}

for {
isDone, nextURL, e := f(start)

if e != nil {
err = e
break
}

if isDone {
break
}

if nextURL != "" {
start, err = getStartToken(nextURL)
if err != nil {
break
}
} else {
break
}
}

return
}
8 changes: 8 additions & 0 deletions internal/ibmcloud-janitor/resources/vpc_client.go
Expand Up @@ -78,6 +78,14 @@ func (c *IBMVPCClient) UnsetSubnetPublicGateway(options *vpcv1.UnsetSubnetPublic
return c.vpcService.UnsetSubnetPublicGateway(options)
}

func (c *IBMVPCClient) DeleteLoadBalancer(options *vpcv1.DeleteLoadBalancerOptions) (*core.DetailedResponse, error) {
return c.vpcService.DeleteLoadBalancer(options)
}

func (c *IBMVPCClient) ListLoadBalancers(options *vpcv1.ListLoadBalancersOptions) (*vpcv1.LoadBalancerCollection, *core.DetailedResponse, error) {
return c.vpcService.ListLoadBalancers(options)
}

// Creates a new VPC Client
func NewVPCClient(options *CleanupOptions) (*IBMVPCClient, error) {
client := &IBMVPCClient{}
Expand Down
71 changes: 71 additions & 0 deletions internal/ibmcloud-janitor/resources/vpc_lbs.go
@@ -0,0 +1,71 @@
/*
Copyright 2022 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 resources

import (
"github.com/IBM/vpc-go-sdk/vpcv1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)

type VPCLoadBalancer struct{}

// Cleans up the load balancers in a given region
func (VPCLoadBalancer) cleanup(options *CleanupOptions) error {
resourceLogger := logrus.WithFields(logrus.Fields{"resource": options.Resource.Name})
resourceLogger.Info("Cleaning up the load balancers")
client, err := NewVPCClient(options)
if err != nil {
return errors.Wrap(err, "couldn't create VPC client")
}

f := func(start string) (bool, string, error) {
listLbOpts := &vpcv1.ListLoadBalancersOptions{}
if start != "" {
listLbOpts.Start = &start
}

loadBalancers, _, err := client.ListLoadBalancers(listLbOpts)
if err != nil {
return false, "", errors.Wrap(err, "failed to list the load balancers")
}

if loadBalancers == nil || len(loadBalancers.LoadBalancers) <= 0 {
resourceLogger.Info("there are no available load balancers to delete")
return true, "", nil
}

for _, lb := range loadBalancers.LoadBalancers {
if lb.ResourceGroup.ID == &client.ResourceGroupID {
_, err := client.DeleteLoadBalancer(&vpcv1.DeleteLoadBalancerOptions{
ID: lb.ID,
})
if err != nil {
return false, "", errors.Wrapf(err, "failed to delete the load balancer %q", *lb.Name)
}
}
}

if loadBalancers.Next != nil && *loadBalancers.Next.Href != "" {
return false, *loadBalancers.Next.Href, nil
}
resourceLogger.Info("Successfully deleted the load balancers")
return true, "", nil
}

return pagingHelper(f)
}

0 comments on commit 95bd75d

Please sign in to comment.