Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add load balancer support via all its components #44

Merged
merged 5 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 2 additions & 170 deletions go.sum

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions pkg/commands/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@ func execute(c *cli.Context) error {
reg := registry.GetRegistration(name)

if reg.AlternativeResource != "" {
color.New(color.Bold).Printf("%-55s\n", name)
color.New(color.Bold, color.FgYellow).Printf(" > %-55s", reg.AlternativeResource)
color.New(color.FgCyan).Printf("alternative resource\n")
_, _ = color.New(color.Bold).Printf("%-55s\n", name)
_, _ = color.New(color.Bold, color.FgYellow).Printf(" > %-55s", reg.AlternativeResource)
_, _ = color.New(color.FgCyan).Printf("alternative resource\n")
} else {
color.New(color.Bold).Printf("%-55s", name)
_, _ = color.New(color.Bold).Printf("%-55s", name)
c := color.FgGreen
if reg.Scope == nuke.Organization {
c = color.FgHiGreen
} else if reg.Scope == nuke.Project {
c = color.FgHiBlue
}
color.New(c).Printf(fmt.Sprintf("%s\n", string(reg.Scope)))
_, _ = color.New(c).Printf(fmt.Sprintf("%s\n", string(reg.Scope))) // nolint: govet
}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/nuke/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type ListerOpts struct {
func (o *ListerOpts) BeforeList(geo Geography, service string) error {
log := logrus.WithField("geo", geo).
WithField("service", service).
WithField("hooke", "true")
WithField("hook", "true")

if geo == Global && *o.Region != "global" {
log.Trace("before-list: skipping resource, global")
Expand Down
202 changes: 202 additions & 0 deletions resources/compute-backend-service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
package resources

import (
"context"
"errors"
"fmt"

"github.com/sirupsen/logrus"

"google.golang.org/api/iterator"

compute "cloud.google.com/go/compute/apiv1"
"cloud.google.com/go/compute/apiv1/computepb"

liberror "github.com/ekristen/libnuke/pkg/errors"
"github.com/ekristen/libnuke/pkg/registry"
"github.com/ekristen/libnuke/pkg/resource"
"github.com/ekristen/libnuke/pkg/types"

"github.com/ekristen/gcp-nuke/pkg/nuke"
)

const ComputeBackendServiceResource = "ComputeBackendService"

func init() {
registry.Register(&registry.Registration{
Name: ComputeBackendServiceResource,
Scope: nuke.Project,
Lister: &ComputeBackendServiceLister{},
})
}

type ComputeBackendServiceLister struct {
svc *compute.RegionBackendServicesClient
globalSvc *compute.BackendServicesClient
}

func (l *ComputeBackendServiceLister) List(ctx context.Context, o interface{}) ([]resource.Resource, error) {
var resources []resource.Resource
opts := o.(*nuke.ListerOpts)

if err := opts.BeforeList(nuke.Global, "compute.googleapis.com"); err == nil {
globalResources, err := l.listGlobal(ctx, opts)
if err != nil {
logrus.WithError(err).Error("unable to list global ssl certificates")
} else {
resources = append(resources, globalResources...)
}
}

if err := opts.BeforeList(nuke.Regional, "compute.googleapis.com"); err == nil {
regionalResources, err := l.listRegional(ctx, opts)
if err != nil {
logrus.WithError(err).Error("unable to list regional ssl certificates")
} else {
resources = append(resources, regionalResources...)
}
}

return resources, nil
}

func (l *ComputeBackendServiceLister) listGlobal(ctx context.Context, opts *nuke.ListerOpts) ([]resource.Resource, error) {
var resources []resource.Resource

if l.globalSvc == nil {
var err error
l.globalSvc, err = compute.NewBackendServicesRESTClient(ctx)
if err != nil {
return nil, err
}
}

req := &computepb.ListBackendServicesRequest{
Project: *opts.Project,
}
it := l.globalSvc.List(ctx, req)
for {
resp, err := it.Next()
if errors.Is(err, iterator.Done) {
break
}
if err != nil {
logrus.WithError(err).Error("unable to iterate networks")
break
}

resources = append(resources, &ComputeBackendService{
globalSvc: l.globalSvc,
project: opts.Project,
Name: resp.Name,
})
}

return resources, nil
}

func (l *ComputeBackendServiceLister) listRegional(ctx context.Context, opts *nuke.ListerOpts) ([]resource.Resource, error) {
var resources []resource.Resource

if l.svc == nil {
var err error
l.svc, err = compute.NewRegionBackendServicesRESTClient(ctx)
if err != nil {
return nil, err
}
}

req := &computepb.ListRegionBackendServicesRequest{
Project: *opts.Project,
Region: *opts.Region,
}
it := l.svc.List(ctx, req)
for {
resp, err := it.Next()
if errors.Is(err, iterator.Done) {
break
}
if err != nil {
logrus.WithError(err).Error("unable to iterate networks")
break
}

resources = append(resources, &ComputeBackendService{
svc: l.svc,
project: opts.Project,
region: opts.Region,
Name: resp.Name,
})
}

return resources, nil
}

type ComputeBackendService struct {
svc *compute.RegionBackendServicesClient
globalSvc *compute.BackendServicesClient
removeOp *compute.Operation
project *string
region *string
Name *string
}

func (r *ComputeBackendService) Remove(ctx context.Context) error {
if r.svc != nil {
return r.removeRegion(ctx)
} else if r.globalSvc != nil {
return r.removeGlobal(ctx)
}

return errors.New("unable to determine service")
}

func (r *ComputeBackendService) removeGlobal(ctx context.Context) (err error) {
r.removeOp, err = r.globalSvc.Delete(ctx, &computepb.DeleteBackendServiceRequest{
Project: *r.project,
BackendService: *r.Name,
})
return err
}

func (r *ComputeBackendService) removeRegion(ctx context.Context) (err error) {
r.removeOp, err = r.svc.Delete(ctx, &computepb.DeleteRegionBackendServiceRequest{
Project: *r.project,
Region: *r.region,
BackendService: *r.Name,
})
return err
}

func (r *ComputeBackendService) Properties() types.Properties {
return types.NewPropertiesFromStruct(r)
}

func (r *ComputeBackendService) String() string {
return *r.Name
}

func (r *ComputeBackendService) HandleWait(ctx context.Context) error {
if r.removeOp == nil {
return nil
}

if err := r.removeOp.Poll(ctx); err != nil {
logrus.WithError(err).Trace("remove op polling encountered error")
return err
}

if !r.removeOp.Done() {
return liberror.ErrWaitResource("waiting for operation to complete")
}

if r.removeOp.Done() {
if r.removeOp.Proto().GetError() != nil {
removeErr := fmt.Errorf("delete error on '%s': %s", r.removeOp.Proto().GetTargetLink(), r.removeOp.Proto().GetHttpErrorMessage())
logrus.WithError(removeErr).WithField("status_code", r.removeOp.Proto().GetError()).Errorf("unable to delete %s", ComputeBackendServiceResource)
return removeErr
}
}

return nil
}
Loading
Loading