gogreen/tags.go

248 lines
7.3 KiB
Go
Raw Normal View History

2016-03-17 04:34:29 +00:00
package godo
2016-11-29 02:42:23 +00:00
import (
"context"
2016-11-29 02:42:23 +00:00
"fmt"
"net/http"
2016-11-29 02:42:23 +00:00
)
2016-03-17 04:34:29 +00:00
const tagsBasePath = "v2/tags"
2016-03-17 05:49:14 +00:00
// TagsService is an interface for interfacing with the tags
// endpoints of the DigitalOcean API
// See: https://docs.digitalocean.com/reference/api/api-reference/#tag/Tags
2016-03-17 04:34:29 +00:00
type TagsService interface {
2016-11-29 02:42:23 +00:00
List(context.Context, *ListOptions) ([]Tag, *Response, error)
Get(context.Context, string) (*Tag, *Response, error)
Create(context.Context, *TagCreateRequest) (*Tag, *Response, error)
Delete(context.Context, string) (*Response, error)
2016-03-17 04:34:29 +00:00
2016-11-29 02:42:23 +00:00
TagResources(context.Context, string, *TagResourcesRequest) (*Response, error)
UntagResources(context.Context, string, *UntagResourcesRequest) (*Response, error)
2016-03-17 04:34:29 +00:00
}
2016-03-17 05:49:14 +00:00
// TagsServiceOp handles communication with tag related method of the
// DigitalOcean API.
2016-03-17 04:34:29 +00:00
type TagsServiceOp struct {
client *Client
}
var _ TagsService = &TagsServiceOp{}
2016-03-22 14:25:22 +00:00
// ResourceType represents a class of resource, currently only droplet are supported
type ResourceType string
const (
2019-03-14 19:52:32 +00:00
// DropletResourceType holds the string representing our ResourceType of Droplet.
2016-03-22 14:25:22 +00:00
DropletResourceType ResourceType = "droplet"
2019-03-14 19:52:32 +00:00
// ImageResourceType holds the string representing our ResourceType of Image.
2018-09-04 14:08:59 +00:00
ImageResourceType ResourceType = "image"
2019-03-14 19:52:32 +00:00
// VolumeResourceType holds the string representing our ResourceType of Volume.
2019-02-08 16:12:32 +00:00
VolumeResourceType ResourceType = "volume"
2019-03-14 19:52:32 +00:00
// LoadBalancerResourceType holds the string representing our ResourceType of LoadBalancer.
LoadBalancerResourceType ResourceType = "load_balancer"
2019-03-14 19:52:32 +00:00
// VolumeSnapshotResourceType holds the string representing our ResourceType for storage Snapshots.
VolumeSnapshotResourceType ResourceType = "volume_snapshot"
// DatabaseResourceType holds the string representing our ResourceType of Database.
DatabaseResourceType ResourceType = "database"
2016-03-22 14:25:22 +00:00
)
// Resource represent a single resource for associating/disassociating with tags
2016-03-17 04:34:29 +00:00
type Resource struct {
ID string `json:"resource_id,omitempty"`
Type ResourceType `json:"resource_type,omitempty"`
2016-03-17 04:34:29 +00:00
}
2016-03-17 05:49:14 +00:00
// TaggedResources represent the set of resources a tag is attached to
2016-03-17 04:34:29 +00:00
type TaggedResources struct {
Count int `json:"count"`
LastTaggedURI string `json:"last_tagged_uri,omitempty"`
Droplets *TaggedDropletsResources `json:"droplets,omitempty"`
Images *TaggedImagesResources `json:"images"`
Volumes *TaggedVolumesResources `json:"volumes"`
VolumeSnapshots *TaggedVolumeSnapshotsResources `json:"volume_snapshots"`
Databases *TaggedDatabasesResources `json:"databases"`
2016-03-17 04:34:29 +00:00
}
2016-03-17 05:49:14 +00:00
// TaggedDropletsResources represent the droplet resources a tag is attached to
2016-03-17 04:34:29 +00:00
type TaggedDropletsResources struct {
2018-09-04 14:08:59 +00:00
Count int `json:"count,float64,omitempty"`
LastTagged *Droplet `json:"last_tagged,omitempty"`
LastTaggedURI string `json:"last_tagged_uri,omitempty"`
}
// TaggedResourcesData represent the generic resources a tag is attached to
2019-02-08 16:12:32 +00:00
type TaggedResourcesData struct {
2018-09-04 14:08:59 +00:00
Count int `json:"count,float64,omitempty"`
LastTaggedURI string `json:"last_tagged_uri,omitempty"`
2016-03-17 04:34:29 +00:00
}
// TaggedImagesResources represent the image resources a tag is attached to
2019-02-08 16:12:32 +00:00
type TaggedImagesResources TaggedResourcesData
// TaggedVolumesResources represent the volume resources a tag is attached to
2019-02-08 16:12:32 +00:00
type TaggedVolumesResources TaggedResourcesData
// TaggedVolumeSnapshotsResources represent the volume snapshot resources a tag is attached to
type TaggedVolumeSnapshotsResources TaggedResourcesData
// TaggedDatabasesResources represent the database resources a tag is attached to
type TaggedDatabasesResources TaggedResourcesData
2016-03-17 05:49:14 +00:00
// Tag represent DigitalOcean tag
2016-03-17 04:34:29 +00:00
type Tag struct {
Name string `json:"name,omitempty"`
Resources *TaggedResources `json:"resources,omitempty"`
}
2016-12-21 00:00:17 +00:00
//TagCreateRequest represents the JSON structure of a request of that type.
2016-03-17 04:34:29 +00:00
type TagCreateRequest struct {
Name string `json:"name"`
}
2016-12-21 00:00:17 +00:00
// TagResourcesRequest represents the JSON structure of a request of that type.
2016-03-17 04:34:29 +00:00
type TagResourcesRequest struct {
Resources []Resource `json:"resources"`
}
2016-12-21 00:00:17 +00:00
// UntagResourcesRequest represents the JSON structure of a request of that type.
2016-03-17 04:34:29 +00:00
type UntagResourcesRequest struct {
Resources []Resource `json:"resources"`
}
type tagsRoot struct {
Tags []Tag `json:"tags"`
2022-08-14 17:34:48 +00:00
Links []*LinkAction `json:"links"`
Meta *Meta `json:"meta"`
2016-03-17 04:34:29 +00:00
}
type tagRoot struct {
Tag *Tag `json:"tag"`
}
// List all tags
2016-11-29 02:42:23 +00:00
func (s *TagsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Tag, *Response, error) {
2016-03-17 04:34:29 +00:00
path := tagsBasePath
path, err := addOptions(path, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
2016-03-17 04:34:29 +00:00
if err != nil {
return nil, nil, err
}
root := new(tagsRoot)
resp, err := s.client.Do(ctx, req, root)
2016-03-17 04:34:29 +00:00
if err != nil {
return nil, resp, err
}
if l := root.Links; l != nil {
resp.Links = l
}
if m := root.Meta; m != nil {
resp.Meta = m
}
2016-03-17 04:34:29 +00:00
return root.Tags, resp, err
}
2016-03-17 05:49:14 +00:00
// Get a single tag
2016-11-29 02:42:23 +00:00
func (s *TagsServiceOp) Get(ctx context.Context, name string) (*Tag, *Response, error) {
2016-03-17 04:34:29 +00:00
path := fmt.Sprintf("%s/%s", tagsBasePath, name)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
2016-03-17 04:34:29 +00:00
if err != nil {
return nil, nil, err
}
root := new(tagRoot)
resp, err := s.client.Do(ctx, req, root)
2016-03-17 04:34:29 +00:00
if err != nil {
return nil, resp, err
}
return root.Tag, resp, err
}
2016-03-17 05:49:14 +00:00
// Create a new tag
2016-11-29 02:42:23 +00:00
func (s *TagsServiceOp) Create(ctx context.Context, createRequest *TagCreateRequest) (*Tag, *Response, error) {
2016-03-17 04:34:29 +00:00
if createRequest == nil {
return nil, nil, NewArgError("createRequest", "cannot be nil")
}
req, err := s.client.NewRequest(ctx, http.MethodPost, tagsBasePath, createRequest)
2016-03-17 04:34:29 +00:00
if err != nil {
return nil, nil, err
}
root := new(tagRoot)
resp, err := s.client.Do(ctx, req, root)
2016-03-17 04:34:29 +00:00
if err != nil {
return nil, resp, err
}
return root.Tag, resp, err
}
2016-03-17 05:49:14 +00:00
// Delete an existing tag
2016-11-29 02:42:23 +00:00
func (s *TagsServiceOp) Delete(ctx context.Context, name string) (*Response, error) {
2016-03-17 04:34:29 +00:00
if name == "" {
return nil, NewArgError("name", "cannot be empty")
}
path := fmt.Sprintf("%s/%s", tagsBasePath, name)
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
2016-03-17 04:34:29 +00:00
if err != nil {
return nil, err
}
resp, err := s.client.Do(ctx, req, nil)
2016-03-17 04:34:29 +00:00
return resp, err
}
2016-12-21 00:00:17 +00:00
// TagResources associates resources with a given Tag.
2016-11-29 02:42:23 +00:00
func (s *TagsServiceOp) TagResources(ctx context.Context, name string, tagRequest *TagResourcesRequest) (*Response, error) {
2016-03-17 04:34:29 +00:00
if name == "" {
return nil, NewArgError("name", "cannot be empty")
}
if tagRequest == nil {
return nil, NewArgError("tagRequest", "cannot be nil")
}
path := fmt.Sprintf("%s/%s/resources", tagsBasePath, name)
req, err := s.client.NewRequest(ctx, http.MethodPost, path, tagRequest)
2016-03-17 04:34:29 +00:00
if err != nil {
return nil, err
}
resp, err := s.client.Do(ctx, req, nil)
2016-03-17 04:34:29 +00:00
return resp, err
}
2016-12-21 00:00:17 +00:00
// UntagResources dissociates resources with a given Tag.
2016-11-29 02:42:23 +00:00
func (s *TagsServiceOp) UntagResources(ctx context.Context, name string, untagRequest *UntagResourcesRequest) (*Response, error) {
2016-03-17 04:34:29 +00:00
if name == "" {
return nil, NewArgError("name", "cannot be empty")
}
if untagRequest == nil {
return nil, NewArgError("tagRequest", "cannot be nil")
}
path := fmt.Sprintf("%s/%s/resources", tagsBasePath, name)
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, untagRequest)
2016-03-17 04:34:29 +00:00
if err != nil {
return nil, err
}
resp, err := s.client.Do(ctx, req, nil)
2016-03-17 04:34:29 +00:00
return resp, err
}