diff --git a/cloud-controller-manager/do/loadbalancers.go b/cloud-controller-manager/do/loadbalancers.go index 8e2ffe1ff..3814a476d 100644 --- a/cloud-controller-manager/do/loadbalancers.go +++ b/cloud-controller-manager/do/loadbalancers.go @@ -145,12 +145,20 @@ func (l *loadBalancers) GetLoadBalancer(ctx context.Context, clusterName string, return nil, false, err } - return &v1.LoadBalancerStatus{ - Ingress: []v1.LoadBalancerIngress{ - { - IP: lb.IP, - }, + ingress := []v1.LoadBalancerIngress{ + { + IP: lb.IP, }, + } + + if lb.IPv6 != "" { + ingress = append(ingress, v1.LoadBalancerIngress{ + IP: lb.IPv6, + }) + } + + return &v1.LoadBalancerStatus{ + Ingress: ingress, }, true, nil } @@ -244,13 +252,19 @@ func (l *loadBalancers) EnsureLoadBalancer(ctx context.Context, clusterName stri }, nil } - return &v1.LoadBalancerStatus{ - Ingress: []v1.LoadBalancerIngress{ - { - IP: lb.IP, - }, + ingress := []v1.LoadBalancerIngress{ + { + IP: lb.IP, }, - }, nil + } + + if lb.IPv6 != "" { + ingress = append(ingress, v1.LoadBalancerIngress{ + IP: lb.IPv6, + }) + } + + return &v1.LoadBalancerStatus{Ingress: ingress}, nil } func getCertificateIDFromLB(lb *godo.LoadBalancer) string { diff --git a/cloud-controller-manager/do/loadbalancers_test.go b/cloud-controller-manager/do/loadbalancers_test.go index 380fa1879..d6e43a442 100644 --- a/cloud-controller-manager/do/loadbalancers_test.go +++ b/cloud-controller-manager/do/loadbalancers_test.go @@ -132,6 +132,7 @@ func createLB() *godo.LoadBalancer { ID: "load-balancer-id", Name: "afoobar123", IP: "10.0.0.1", + IPv6: "fd53::b001", Status: lbStatusActive, } } @@ -141,6 +142,7 @@ func createHTTPSLB(lbID, certID, certType string) (*godo.LoadBalancer, *godo.Cer ID: lbID, Name: "afoobar123", IP: "10.0.0.1", + IPv6: "fd53::b001", Status: lbStatusActive, ForwardingRules: []godo.ForwardingRule{ { @@ -4999,6 +5001,7 @@ func Test_GetLoadBalancer(t *testing.T) { ID: "load-balancer-id", Name: "afoobar123", IP: "10.0.0.1", + IPv6: "fd53::b001", Status: lbStatusActive, }, }, newFakeOKResponse(), nil @@ -5028,6 +5031,9 @@ func Test_GetLoadBalancer(t *testing.T) { { IP: "10.0.0.1", }, + { + IP: "fd53::b001", + }, }, }, exists: true, @@ -5041,6 +5047,7 @@ func Test_GetLoadBalancer(t *testing.T) { ID: "load-balancer-id", Name: "my-load-balancer-123", IP: "10.0.0.1", + IPv6: "fd53::b001", Status: lbStatusActive, }, }, newFakeOKResponse(), nil @@ -5071,6 +5078,9 @@ func Test_GetLoadBalancer(t *testing.T) { { IP: "10.0.0.1", }, + { + IP: "fd53::b001", + }, }, }, exists: true, @@ -5084,6 +5094,7 @@ func Test_GetLoadBalancer(t *testing.T) { ID: "load-balancer-id", Name: "afoobar123", IP: "10.0.0.1", + IPv6: "fd53::b001", Status: lbStatusActive, }, }, newFakeOKResponse(), nil @@ -5103,6 +5114,9 @@ func Test_GetLoadBalancer(t *testing.T) { { IP: "10.0.0.1", }, + { + IP: "fd53::b001", + }, }, }, exists: true, @@ -5115,6 +5129,7 @@ func Test_GetLoadBalancer(t *testing.T) { ID: "load-balancer-id", Name: "afoobar123", IP: "10.0.0.1", + IPv6: "fd53::b001", Status: lbStatusActive, }, newFakeOKResponse(), nil }, @@ -5147,6 +5162,9 @@ func Test_GetLoadBalancer(t *testing.T) { { IP: "10.0.0.1", }, + { + IP: "fd53::b001", + }, }, }, exists: true, @@ -5321,6 +5339,9 @@ func Test_EnsureLoadBalancer(t *testing.T) { { IP: "10.0.0.1", }, + { + IP: "fd53::b001", + }, }, }, err: nil, @@ -5395,6 +5416,9 @@ func Test_EnsureLoadBalancer(t *testing.T) { { IP: "10.0.0.1", }, + { + IP: "fd53::b001", + }, }, }, err: nil, @@ -5468,6 +5492,9 @@ func Test_EnsureLoadBalancer(t *testing.T) { { IP: "10.0.0.1", }, + { + IP: "fd53::b001", + }, }, }, err: nil, @@ -5545,6 +5572,9 @@ func Test_EnsureLoadBalancer(t *testing.T) { { IP: "10.0.0.1", }, + { + IP: "fd53::b001", + }, }, }, err: nil, @@ -5632,6 +5662,9 @@ func Test_EnsureLoadBalancer(t *testing.T) { { IP: "10.0.0.1", }, + { + IP: "fd53::b001", + }, }, }, }, @@ -5642,6 +5675,9 @@ func Test_EnsureLoadBalancer(t *testing.T) { { IP: "10.0.0.1", }, + { + IP: "fd53::b001", + }, }, }, err: nil, @@ -5758,6 +5794,7 @@ func Test_EnsureLoadBalancerDeleted(t *testing.T) { { Name: lbName, IP: "10.0.0.1", + IPv6: "fd53::b001", Status: lbStatusActive, }, }, newFakeOKResponse(), nil @@ -5780,6 +5817,7 @@ func Test_EnsureLoadBalancerDeleted(t *testing.T) { { Name: lbName, IP: "10.0.0.1", + IPv6: "fd53::b001", Status: lbStatusActive, }, }, newFakeOKResponse(), nil diff --git a/go.mod b/go.mod index 5fe865ff7..6ce8f4e4b 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.23.0 require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc - github.com/digitalocean/godo v1.130.0 + github.com/digitalocean/godo v1.131.0 github.com/go-logr/logr v1.4.2 github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 diff --git a/go.sum b/go.sum index 39d5bc3cd..af1e518f1 100644 --- a/go.sum +++ b/go.sum @@ -25,8 +25,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/digitalocean/godo v1.130.0 h1:DbJg0wvBxTkYjY5Q9S1mwzAZLd5Wht3r57yFH4yeMCk= -github.com/digitalocean/godo v1.130.0/go.mod h1:PU8JB6I1XYkQIdHFop8lLAY9ojp6M0XcU0TWaQSxbrc= +github.com/digitalocean/godo v1.131.0 h1:0WHymufAV5avpodT0h5/pucUVfO4v7biquOIqhLeROY= +github.com/digitalocean/godo v1.131.0/go.mod h1:PU8JB6I1XYkQIdHFop8lLAY9ojp6M0XcU0TWaQSxbrc= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/emicklei/go-restful/v3 v3.12.0 h1:y2DdzBAURM29NFF94q6RaY4vjIH1rtwDapwQtU84iWk= diff --git a/vendor/github.com/digitalocean/godo/CHANGELOG.md b/vendor/github.com/digitalocean/godo/CHANGELOG.md index 68e7d48f5..3fb2a160c 100644 --- a/vendor/github.com/digitalocean/godo/CHANGELOG.md +++ b/vendor/github.com/digitalocean/godo/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## [v1.131.0] - 2024-11-25 + +- #760 - @jvasilevsky - LBAAS: add ipv6 field to loadbalancer model +- #759 - @imaskm - Add reserved ipv6 changes as Beta +- #758 - @dvigueras - Add Rules field to create Databases with Firewall Rules +- #751 - @blesswinsamuel - APPS-9766 Add method to restart apps + + ## [v1.130.0] - 2024-11-14 - #755 - @vsharma6855 - Add Missing Database Configs for Postgresql and MYSQL diff --git a/vendor/github.com/digitalocean/godo/apps.gen.go b/vendor/github.com/digitalocean/godo/apps.gen.go index 0232ae943..6fc029cb9 100644 --- a/vendor/github.com/digitalocean/godo/apps.gen.go +++ b/vendor/github.com/digitalocean/godo/apps.gen.go @@ -466,8 +466,7 @@ type AppLogDestinationSpecPapertrail struct { type AppMaintenanceSpec struct { // Indicates whether maintenance mode should be enabled for the app. Enabled bool `json:"enabled,omitempty"` - // Indicates whether the app should be archived. Setting this to true implies that enabled is set to true. - // Note that this feature is currently in closed beta. + // Indicates whether the app should be archived. Setting this to true implies that enabled is set to true. Note that this feature is currently in closed beta. Archive bool `json:"archive,omitempty"` } @@ -1004,6 +1003,7 @@ const ( DeploymentCauseDetailsDigitalOceanUserActionName_RollbackApp DeploymentCauseDetailsDigitalOceanUserActionName = "ROLLBACK_APP" DeploymentCauseDetailsDigitalOceanUserActionName_RevertAppRollback DeploymentCauseDetailsDigitalOceanUserActionName = "REVERT_APP_ROLLBACK" DeploymentCauseDetailsDigitalOceanUserActionName_UpgradeBuildpack DeploymentCauseDetailsDigitalOceanUserActionName = "UPGRADE_BUILDPACK" + DeploymentCauseDetailsDigitalOceanUserActionName_Restart DeploymentCauseDetailsDigitalOceanUserActionName = "RESTART" ) // AppDomain struct for AppDomain diff --git a/vendor/github.com/digitalocean/godo/apps.go b/vendor/github.com/digitalocean/godo/apps.go index 24fe738e4..97b0cbd73 100644 --- a/vendor/github.com/digitalocean/godo/apps.go +++ b/vendor/github.com/digitalocean/godo/apps.go @@ -35,6 +35,7 @@ type AppsService interface { Delete(ctx context.Context, appID string) (*Response, error) Propose(ctx context.Context, propose *AppProposeRequest) (*AppProposeResponse, *Response, error) + Restart(ctx context.Context, appID string, opts *AppRestartRequest) (*Deployment, *Response, error) GetDeployment(ctx context.Context, appID, deploymentID string) (*Deployment, *Response, error) ListDeployments(ctx context.Context, appID string, opts *ListOptions) ([]*Deployment, *Response, error) CreateDeployment(ctx context.Context, appID string, create ...*DeploymentCreateRequest) (*Deployment, *Response, error) @@ -95,6 +96,11 @@ type DeploymentCreateRequest struct { ForceBuild bool `json:"force_build"` } +// AppRestartRequest represents a request to restart an app. +type AppRestartRequest struct { + Components []string `json:"components"` +} + // AlertDestinationUpdateRequest represents a request to update alert destinations. type AlertDestinationUpdateRequest struct { Emails []string `json:"emails"` @@ -285,6 +291,22 @@ func (s *AppsServiceOp) Propose(ctx context.Context, propose *AppProposeRequest) return res, resp, nil } +// Restart restarts an app. +func (s *AppsServiceOp) Restart(ctx context.Context, appID string, opts *AppRestartRequest) (*Deployment, *Response, error) { + path := fmt.Sprintf("%s/%s/restart", appsBasePath, appID) + + req, err := s.client.NewRequest(ctx, http.MethodPost, path, opts) + if err != nil { + return nil, nil, err + } + root := new(deploymentRoot) + resp, err := s.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + return root.Deployment, resp, nil +} + // GetDeployment gets an app deployment. func (s *AppsServiceOp) GetDeployment(ctx context.Context, appID, deploymentID string) (*Deployment, *Response, error) { path := fmt.Sprintf("%s/%s/deployments/%s", appsBasePath, appID, deploymentID) diff --git a/vendor/github.com/digitalocean/godo/databases.go b/vendor/github.com/digitalocean/godo/databases.go index e2a7d567c..1217ef05e 100644 --- a/vendor/github.com/digitalocean/godo/databases.go +++ b/vendor/github.com/digitalocean/godo/databases.go @@ -299,19 +299,27 @@ type DatabaseBackupRestore struct { BackupCreatedAt string `json:"backup_created_at,omitempty"` } +// DatabaseCreateFirewallRule is a rule describing an inbound source to a database +type DatabaseCreateFirewallRule struct { + UUID string `json:"uuid"` + Type string `json:"type"` + Value string `json:"value"` +} + // DatabaseCreateRequest represents a request to create a database cluster type DatabaseCreateRequest struct { - Name string `json:"name,omitempty"` - EngineSlug string `json:"engine,omitempty"` - Version string `json:"version,omitempty"` - SizeSlug string `json:"size,omitempty"` - Region string `json:"region,omitempty"` - NumNodes int `json:"num_nodes,omitempty"` - PrivateNetworkUUID string `json:"private_network_uuid"` - Tags []string `json:"tags,omitempty"` - BackupRestore *DatabaseBackupRestore `json:"backup_restore,omitempty"` - ProjectID string `json:"project_id"` - StorageSizeMib uint64 `json:"storage_size_mib,omitempty"` + Name string `json:"name,omitempty"` + EngineSlug string `json:"engine,omitempty"` + Version string `json:"version,omitempty"` + SizeSlug string `json:"size,omitempty"` + Region string `json:"region,omitempty"` + NumNodes int `json:"num_nodes,omitempty"` + PrivateNetworkUUID string `json:"private_network_uuid"` + Tags []string `json:"tags,omitempty"` + BackupRestore *DatabaseBackupRestore `json:"backup_restore,omitempty"` + ProjectID string `json:"project_id"` + StorageSizeMib uint64 `json:"storage_size_mib,omitempty"` + Rules []*DatabaseCreateFirewallRule `json:"rules"` } // DatabaseResizeRequest can be used to initiate a database resize operation. diff --git a/vendor/github.com/digitalocean/godo/godo.go b/vendor/github.com/digitalocean/godo/godo.go index 4b9ad6b61..62498fc44 100644 --- a/vendor/github.com/digitalocean/godo/godo.go +++ b/vendor/github.com/digitalocean/godo/godo.go @@ -21,7 +21,7 @@ import ( ) const ( - libraryVersion = "1.130.0" + libraryVersion = "1.131.0" defaultBaseURL = "https://api.digitalocean.com/" userAgent = "godo/" + libraryVersion mediaType = "application/json" @@ -54,43 +54,45 @@ type Client struct { ratemtx sync.Mutex // Services used for communicating with the API - Account AccountService - Actions ActionsService - Apps AppsService - Balance BalanceService - BillingHistory BillingHistoryService - CDNs CDNService - Certificates CertificatesService - Databases DatabasesService - Domains DomainsService - Droplets DropletsService - DropletActions DropletActionsService - DropletAutoscale DropletAutoscaleService - Firewalls FirewallsService - FloatingIPs FloatingIPsService - FloatingIPActions FloatingIPActionsService - Functions FunctionsService - Images ImagesService - ImageActions ImageActionsService - Invoices InvoicesService - Keys KeysService - Kubernetes KubernetesService - LoadBalancers LoadBalancersService - Monitoring MonitoringService - OneClick OneClickService - Projects ProjectsService - Regions RegionsService - Registry RegistryService - Registries RegistriesService - ReservedIPs ReservedIPsService - ReservedIPActions ReservedIPActionsService - Sizes SizesService - Snapshots SnapshotsService - Storage StorageService - StorageActions StorageActionsService - Tags TagsService - UptimeChecks UptimeChecksService - VPCs VPCsService + Account AccountService + Actions ActionsService + Apps AppsService + Balance BalanceService + BillingHistory BillingHistoryService + CDNs CDNService + Certificates CertificatesService + Databases DatabasesService + Domains DomainsService + Droplets DropletsService + DropletActions DropletActionsService + DropletAutoscale DropletAutoscaleService + Firewalls FirewallsService + FloatingIPs FloatingIPsService + FloatingIPActions FloatingIPActionsService + Functions FunctionsService + Images ImagesService + ImageActions ImageActionsService + Invoices InvoicesService + Keys KeysService + Kubernetes KubernetesService + LoadBalancers LoadBalancersService + Monitoring MonitoringService + OneClick OneClickService + Projects ProjectsService + Regions RegionsService + Registry RegistryService + Registries RegistriesService + ReservedIPs ReservedIPsService + ReservedIPV6s ReservedIPV6sService + ReservedIPActions ReservedIPActionsService + ReservedIPV6Actions ReservedIPV6ActionsService + Sizes SizesService + Snapshots SnapshotsService + Storage StorageService + StorageActions StorageActionsService + Tags TagsService + UptimeChecks UptimeChecksService + VPCs VPCsService // Optional function called after every successful request made to the DO APIs onRequestCompleted RequestCompletionCallback @@ -295,7 +297,9 @@ func NewClient(httpClient *http.Client) *Client { c.Registry = &RegistryServiceOp{client: c} c.Registries = &RegistriesServiceOp{client: c} c.ReservedIPs = &ReservedIPsServiceOp{client: c} + c.ReservedIPV6s = &ReservedIPV6sServiceOp{client: c} c.ReservedIPActions = &ReservedIPActionsServiceOp{client: c} + c.ReservedIPV6Actions = &ReservedIPV6ActionsServiceOp{client: c} c.Sizes = &SizesServiceOp{client: c} c.Snapshots = &SnapshotsServiceOp{client: c} c.Storage = &StorageServiceOp{client: c} diff --git a/vendor/github.com/digitalocean/godo/load_balancers.go b/vendor/github.com/digitalocean/godo/load_balancers.go index a24952b71..a12729dd6 100644 --- a/vendor/github.com/digitalocean/godo/load_balancers.go +++ b/vendor/github.com/digitalocean/godo/load_balancers.go @@ -45,6 +45,7 @@ type LoadBalancer struct { ID string `json:"id,omitempty"` Name string `json:"name,omitempty"` IP string `json:"ip,omitempty"` + IPv6 string `json:"ipv6,omitempty"` // SizeSlug is mutually exclusive with SizeUnit. Only one should be specified SizeSlug string `json:"size,omitempty"` // SizeUnit is mutually exclusive with SizeSlug. Only one should be specified diff --git a/vendor/github.com/digitalocean/godo/reserved_ipv6.go b/vendor/github.com/digitalocean/godo/reserved_ipv6.go new file mode 100644 index 000000000..aa2656359 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/reserved_ipv6.go @@ -0,0 +1,132 @@ +package godo + +import ( + "context" + "fmt" + "net/http" + "time" +) + +const resourceV6Type = "ReservedIPv6" +const reservedIPV6sBasePath = "v2/reserved_ipv6" + +// ReservedIPV6sService is an interface for interfacing with the reserved IPV6s +// endpoints of the Digital Ocean API. +type ReservedIPV6sService interface { + List(context.Context, *ListOptions) ([]ReservedIPV6, *Response, error) + Get(context.Context, string) (*ReservedIPV6, *Response, error) + Create(context.Context, *ReservedIPV6CreateRequest) (*ReservedIPV6, *Response, error) + Delete(context.Context, string) (*Response, error) +} + +// ReservedIPV6sServiceOp handles communication with the reserved IPs related methods of the +// DigitalOcean API. +type ReservedIPV6sServiceOp struct { + client *Client +} + +var _ ReservedIPV6sService = (*ReservedIPV6sServiceOp)(nil) + +// ReservedIPV6 represents a Digital Ocean reserved IP. +type ReservedIPV6 struct { + RegionSlug string `json:"region_slug"` + IP string `json:"ip"` + ReservedAt time.Time `json:"reserved_at"` + Droplet *Droplet `json:"droplet,omitempty"` +} + +func (f ReservedIPV6) String() string { + return Stringify(f) +} + +// URN returns the reserved IP in a valid DO API URN form. +func (f ReservedIPV6) URN() string { + return ToURN(resourceV6Type, f.IP) +} + +type reservedIPV6sRoot struct { + ReservedIPs []ReservedIPV6 `json:"reserved_ips"` + Links *Links `json:"links"` + Meta *Meta `json:"meta"` +} + +// ReservedIPV6CreateRequest represents a request to reserve a reserved IP. +type ReservedIPV6CreateRequest struct { + Region string `json:"region_slug,omitempty"` +} + +// List all reserved IPV6s. +func (r *ReservedIPV6sServiceOp) List(ctx context.Context, opt *ListOptions) ([]ReservedIPV6, *Response, error) { + path := reservedIPV6sBasePath + path, err := addOptions(path, opt) + if err != nil { + return nil, nil, err + } + + req, err := r.client.NewRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + + root := new(reservedIPV6sRoot) + resp, err := r.client.Do(ctx, req, root) + if err != nil { + return nil, nil, err + } + if l := root.Links; l != nil { + resp.Links = l + } + if m := root.Meta; m != nil { + resp.Meta = m + } + + return root.ReservedIPs, resp, err +} + +// Get an individual reserved IPv6. +func (r *ReservedIPV6sServiceOp) Get(ctx context.Context, ip string) (*ReservedIPV6, *Response, error) { + path := fmt.Sprintf("%s/%s", reservedIPV6sBasePath, ip) + + req, err := r.client.NewRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + + root := new(ReservedIPV6) + resp, err := r.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + + return root, resp, err +} + +// Create a new IPv6 +func (r *ReservedIPV6sServiceOp) Create(ctx context.Context, reserveRequest *ReservedIPV6CreateRequest) (*ReservedIPV6, *Response, error) { + path := reservedIPV6sBasePath + + req, err := r.client.NewRequest(ctx, http.MethodPost, path, reserveRequest) + if err != nil { + return nil, nil, err + } + + root := new(ReservedIPV6) + resp, err := r.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + + return root, resp, err +} + +// Delete a reserved IPv6. +func (r *ReservedIPV6sServiceOp) Delete(ctx context.Context, ip string) (*Response, error) { + path := fmt.Sprintf("%s/%s", reservedIPV6sBasePath, ip) + + req, err := r.client.NewRequest(ctx, http.MethodDelete, path, nil) + if err != nil { + return nil, err + } + + return r.client.Do(ctx, req, nil) +} diff --git a/vendor/github.com/digitalocean/godo/reserved_ipv6_actions.go b/vendor/github.com/digitalocean/godo/reserved_ipv6_actions.go new file mode 100644 index 000000000..dd14bc58b --- /dev/null +++ b/vendor/github.com/digitalocean/godo/reserved_ipv6_actions.go @@ -0,0 +1,57 @@ +package godo + +import ( + "context" + "fmt" + "net/http" +) + +// ReservedIPActionsService is an interface for interfacing with the +// reserved IPs actions endpoints of the Digital Ocean API. +// See: https://docs.digitalocean.com/reference/api/api-reference/#tag/Reserved-IP-Actions +type ReservedIPV6ActionsService interface { + Assign(ctx context.Context, ip string, dropletID int) (*Action, *Response, error) + Unassign(ctx context.Context, ip string) (*Action, *Response, error) +} + +// ReservedIPActionsServiceOp handles communication with the reserved IPs +// action related methods of the DigitalOcean API. +type ReservedIPV6ActionsServiceOp struct { + client *Client +} + +// Assign a reserved IP to a droplet. +func (s *ReservedIPV6ActionsServiceOp) Assign(ctx context.Context, ip string, dropletID int) (*Action, *Response, error) { + request := &ActionRequest{ + "type": "assign", + "droplet_id": dropletID, + } + return s.doV6Action(ctx, ip, request) +} + +// Unassign a rerserved IP from the droplet it is currently assigned to. +func (s *ReservedIPV6ActionsServiceOp) Unassign(ctx context.Context, ip string) (*Action, *Response, error) { + request := &ActionRequest{"type": "unassign"} + return s.doV6Action(ctx, ip, request) +} + +func (s *ReservedIPV6ActionsServiceOp) doV6Action(ctx context.Context, ip string, request *ActionRequest) (*Action, *Response, error) { + path := reservedIPV6ActionPath(ip) + + req, err := s.client.NewRequest(ctx, http.MethodPost, path, request) + if err != nil { + return nil, nil, err + } + + root := new(actionRoot) + resp, err := s.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + + return root.Event, resp, err +} + +func reservedIPV6ActionPath(ip string) string { + return fmt.Sprintf("%s/%s/actions", reservedIPV6sBasePath, ip) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index fa14e951b..5f2858438 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -33,7 +33,7 @@ github.com/coreos/go-systemd/v22/journal # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc ## explicit github.com/davecgh/go-spew/spew -# github.com/digitalocean/godo v1.130.0 +# github.com/digitalocean/godo v1.131.0 ## explicit; go 1.22 github.com/digitalocean/godo github.com/digitalocean/godo/metrics