Resources¶
Resources are the core of the tool, they are what is used to list and remove resources from gcp. The resources are broken down into separate files.
When creating a resource there's the base resource type, then there's the Lister
type that returns a list of resources
that it discovers. Those resources are then filtered by any filtering criteria on the resource itself.
Anatomy of a Resource¶
The anatomy of a resource is fairly simple, it's broken down into a few parts:
Resource
- This is the base resource type that is used to define the resource.Lister
- This is the type that is used to list the resources.
Resource¶
The resource must have the func Remove() error
method defined on it, this is what is used to remove the resource.
It can optionally have the following methods defined:
func Filter() error
- This is used to pre-filter resources, usually based on internal criteria, like system defaults.func String() string
- This is used to print the resource in a human-readable format.func Properties() types.Properties
- This is used to print the resource in a human-readable format.
package resources
import (
"context"
"github.com/ekristen/libnuke/pkg/resource"
"github.com/ekristen/libnuke/pkg/types"
"github.com/ekristen/gcp-nuke/pkg/nuke"
)
type ExampleResource struct {
ID *string
}
func (r *ExampleResource) Remove(_ context.Context) error {
// remove the resource, an error will put the resource in failed state
// resources in failed state are retried a number of times
return nil
}
func (r *ExampleResource) Filter() error {
// filter the resource, this is useful for built-in resources that cannot
// be removed, like a gcp managed resource, return an error here to filter
// it before it even gets to the user supplied filters.
return nil
}
func (r *ExampleResource) String() string {
// return a string representation of the resource, this is legacy, but still
// used for a number of reasons.
return *r.ID
}
Lister¶
The lister must have the func List(ctx context.Context, o interface{}) ([]resource.Resource, error)
method defined on it.
package resources
import (
"context"
"github.com/ekristen/libnuke/pkg/resource"
"github.com/ekristen/gcp-nuke/pkg/nuke"
)
type ExampleResourceLister struct{}
func (l *ExampleResourceLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) {
opts := o.(*nuke.ListerOpts)
var resources []resource.Resource
// list the resources and add to resources slice
return resources, nil
}
Example¶
package resources
import (
"context"
"github.com/ekristen/libnuke/pkg/resource"
"github.com/ekristen/libnuke/pkg/types"
"github.com/ekristen/gcp-nuke/pkg/nuke"
)
type ExampleResourceLister struct{}
func (l *ExampleResourceLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) {
opts := o.(*nuke.ListerOpts)
var resources []resource.Resource
// list the resources and add to resources slice
return resources, nil
}
// -----------------------------------------------------------------------------
type ExampleResource struct {
ID *string
}
func (r *ExampleResource) Remove(_ context.Context) error {
// remove the resource, an error will put the resource in failed state
// resources in failed state are retried a number of times
return nil
}
func (r *ExampleResource) Filter() error {
// filter the resource, this is useful for built-in resources that cannot
// be removed, like an gcp managed resource, return an error here to filter
// it before it even gets to the user supplied filters.
return nil
}
func (r *ExampleResource) String() string {
// return a string representation of the resource, this is legacy, but still
// used for a number of reasons.
return *r.ID
}
func (r *ExampleResource) Properties() types.Properties {
// return a properties representation of the resource
props := types.NewProperties()
props.Set("ID", r.ID)
return props
}
Creating a new resource¶
Creating a new resources is fairly straightforward and a template is provided for you, along with a tool to help you generate the boilerplate code.
Currently, the code is generated using a tool that is located in tools/create-resource/main.go
and can be run like so:
Note
At present, the tool does not check if the service or the resource type is valid, this is purely a helper tool to generate the boilerplate code.
go run tools/create-resource/main.go <service> <resource-type>
This will output the boilerplate code to stdout, so you can copy and paste it into the appropriate file or you can redirect to a file like so:
go run tools/create-resource/main.go <service> <resource-type> > resources/<resource-type>.go