Skip to content

Commit

Permalink
Add providers documentation
Browse files Browse the repository at this point in the history
Signed-off-by: Leandro López (inkel) <[email protected]>
  • Loading branch information
inkel committed Dec 20, 2022
1 parent 5f4b5c7 commit 1c93776
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 1 deletion.
13 changes: 13 additions & 0 deletions aws/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,25 @@ import (

var _ unused.Disk = &Disk{}

// Disk holds information about an AWS EC2 volume.
type Disk struct {
types.Volume
provider *Provider
meta unused.Meta
}

// ID returns the volume ID of this AWS EC2 volume.
func (d *Disk) ID() string { return *d.Volume.VolumeId }

// Provider returns a reference to the provider used to instantiate
// this disk.
func (d *Disk) Provider() unused.Provider { return d.provider }

// Name returns the name of this AWS EC2 volume.
//
// AWS EC2 volumes do not have a name property, instead they store the
// name in tags. This method will try to find the Name or
// CSIVolumeName, otherwise it will return empty.
func (d *Disk) Name() string {
for _, t := range d.Volume.Tags {
if *t.Key == "Name" || *t.Key == "CSIVolumeName" {
Expand All @@ -28,8 +37,12 @@ func (d *Disk) Name() string {
return ""
}

// CreatedAt returns the time when the AWS EC2 volume was created.
func (d *Disk) CreatedAt() time.Time { return *d.Volume.CreateTime }

// Meta returns the disk metadata.
func (d *Disk) Meta() unused.Meta { return d.meta }

// LastUsedAt returns a zero [time.Time] value, as AWS does not
// provide this information.
func (d *Disk) LastUsedAt() time.Time { return time.Time{} }
11 changes: 11 additions & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,23 @@ import (

var _ unused.Provider = &Provider{}

// Provider implements [unused.Provider] for AWS.
type Provider struct {
client *ec2.Client
meta unused.Meta
}

// Name returns AWS.
func (p *Provider) Name() string { return "AWS" }

// Meta returns the provider metadata.
func (p *Provider) Meta() unused.Meta { return p.meta }

// NewProvider creates a new AWS [unused.Provider].
//
// A valid EC2 client must be supplied in order to list the unused
// resources. The metadata passed will be used to identify the
// provider.
func NewProvider(client *ec2.Client, meta unused.Meta) (*Provider, error) {
if meta == nil {
meta = make(unused.Meta)
Expand All @@ -32,6 +40,8 @@ func NewProvider(client *ec2.Client, meta unused.Meta) (*Provider, error) {
}, nil
}

// ListUnusedDisks returns all the AWS EC2 volumes that are available,
// ie. not used by any other resource.
func (p *Provider) ListUnusedDisks(ctx context.Context) (unused.Disks, error) {
params := &ec2.DescribeVolumesInput{
Filters: []types.Filter{
Expand Down Expand Up @@ -72,6 +82,7 @@ func (p *Provider) ListUnusedDisks(ctx context.Context) (unused.Disks, error) {
return upds, nil
}

// Delete deletes the given disk from AWS.
func (p *Provider) Delete(ctx context.Context, disk unused.Disk) error {
_, err := p.client.DeleteVolume(ctx, &ec2.DeleteVolumeInput{
VolumeId: aws.String(disk.ID()),
Expand Down
10 changes: 10 additions & 0 deletions azure/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,30 @@ import (

var _ unused.Disk = &Disk{}

// Disk holds information about an Azure compute disk.
type Disk struct {
compute.Disk
provider *Provider
meta unused.Meta
}

// ID returns the Azure compute disk ID.
func (d *Disk) ID() string { return *d.Disk.ID }

// Provider returns a reference to the provider used to instantiate
// this disk.
func (d *Disk) Provider() unused.Provider { return d.provider }

// Name returns the name of this Azure compute disk.
func (d *Disk) Name() string { return *d.Disk.Name }

// CreatedAt returns the time when this Azure compute disk was
// created.
func (d *Disk) CreatedAt() time.Time { return d.Disk.TimeCreated.ToTime() }

// Meta returns the disk metadata.
func (d *Disk) Meta() unused.Meta { return d.meta }

// LastUsedAt returns a zero [time.Time] value, as Azure does not
// provide this information.
func (d *Disk) LastUsedAt() time.Time { return time.Time{} }
10 changes: 10 additions & 0 deletions azure/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,22 @@ var _ unused.Provider = &Provider{}

const ResourceGroupMetaKey = "resource-group"

// Providcer implements [unused.Provider] for Azure.
type Provider struct {
client compute.DisksClient
meta unused.Meta
}

// Name returns Azure.
func (p *Provider) Name() string { return "Azure" }

// Meta returns the provider metadata.
func (p *Provider) Meta() unused.Meta { return p.meta }

// NewProvider creates a new Azure [unused.Provider].
//
// A valid Azure compute disks client must be supplied in order to
// list the unused resources.
func NewProvider(client compute.DisksClient, meta unused.Meta) (*Provider, error) {
if meta == nil {
meta = make(unused.Meta)
Expand All @@ -30,6 +37,8 @@ func NewProvider(client compute.DisksClient, meta unused.Meta) (*Provider, error
return &Provider{client: client, meta: meta}, nil
}

// ListUnusedDisks returns all the Azure compute disks that are not
// managed by other resources.
func (p *Provider) ListUnusedDisks(ctx context.Context) (unused.Disks, error) {
var upds unused.Disks

Expand Down Expand Up @@ -69,6 +78,7 @@ func (p *Provider) ListUnusedDisks(ctx context.Context) (unused.Disks, error) {
return upds, nil
}

// Delete deletes the given disk from Azure.
func (p *Provider) Delete(ctx context.Context, disk unused.Disk) error {
_, err := p.client.Delete(ctx, disk.Meta()[ResourceGroupMetaKey], disk.Name())
if err != nil {
Expand Down
11 changes: 10 additions & 1 deletion gcp/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,36 @@ import (
// ensure we are properly defining the interface
var _ unused.Disk = &Disk{}

// Disk holds information about a GCP compute disk.
type Disk struct {
*compute.Disk
provider *Provider
meta unused.Meta
}

func (d *Disk) ID() string { return fmt.Sprintf("gcp-disk-%d", d.Disk.Id) }
// ID returns the GCP compute disk ID, prefixed by gcp-disk.
func (d *Disk) ID() string { return fmt.Sprintf("gcp-disk-%d", d.Disk.Id) } // TODO remove prefix

// Provider returns a reference to the provider used to instantiate
// this disk.
func (d *Disk) Provider() unused.Provider { return d.provider }

// Name returns the name of the GCP compute disk.
func (d *Disk) Name() string { return d.Disk.Name }

// CreatedAt returns the time when the GCP compute disk was created.
func (d *Disk) CreatedAt() time.Time {
// it's safe to assume GCP will send a valid timestamp
c, _ := time.Parse(time.RFC3339, d.Disk.CreationTimestamp)

return c
}

// Meta returns the disk metadata.
func (d *Disk) Meta() unused.Meta { return d.meta }

// LastUsedAt returns the time when the GCP compute disk was last
// detached.
func (d *Disk) LastUsedAt() time.Time {
// it's safe to assume GCP will send a valid timestamp
t, _ := time.Parse(time.RFC3339, d.Disk.LastDetachTimestamp)
Expand Down
13 changes: 13 additions & 0 deletions gcp/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,30 @@ import (
"google.golang.org/api/compute/v1"
)

// ErrMissingProject is the error used when no project ID is provided
// when trying to create a provider.
var ErrMissingProject = errors.New("missing project id")

var _ unused.Provider = &Provider{}

// Provider implements [unused.Provider] for GCP.
type Provider struct {
project string
svc *compute.Service
meta unused.Meta
}

// Name returns GCP.
func (p *Provider) Name() string { return "GCP" }

// Meta returns the provider metadata.
func (p *Provider) Meta() unused.Meta { return p.meta }

// NewProvider creates a new GCP [unused.Provider].
//
// A valid GCP compute service must be supplied in order to listed the
// unused resources. It also requires a valid project ID which should
// be the project where the disks were created.
func NewProvider(svc *compute.Service, project string, meta unused.Meta) (*Provider, error) {
if project == "" {
return nil, ErrMissingProject
Expand All @@ -41,6 +51,8 @@ func NewProvider(svc *compute.Service, project string, meta unused.Meta) (*Provi
}, nil
}

// ListUnusedDisks returns all the GCP compute disks that aren't
// associated to any users, meaning that are not being in use.
func (p *Provider) ListUnusedDisks(ctx context.Context) (unused.Disks, error) {
var disks unused.Disks

Expand Down Expand Up @@ -85,6 +97,7 @@ func diskMetadata(d *compute.Disk) (unused.Meta, error) {
return m, nil
}

// Delete deletes the given disk from GCP.
func (p *Provider) Delete(ctx context.Context, disk unused.Disk) error {
_, err := p.svc.Disks.Delete(p.project, disk.Meta()["zone"], disk.Name()).Do()
if err != nil {
Expand Down

0 comments on commit 1c93776

Please sign in to comment.