Skip to content

Commit

Permalink
Merge branch 'main' into add-auth-key-field
Browse files Browse the repository at this point in the history
  • Loading branch information
apinonformoso authored Feb 21, 2025
2 parents 6f76411 + 0dcda2a commit 4c22bd3
Show file tree
Hide file tree
Showing 9 changed files with 403 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Checkout code
uses: actions/checkout@v2
- name: Restore cache
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Change Log

## [v1.138.0] - 2025-03-18

- #785 - @guptado - Support partner interconnect GetBgpAuthKey and RegenerateServiceKey operations
- #787 - @andrewsomething - ci: upgrade to actions/cache@v4
- #786 - @m3co-code - add flags for doks routing-agent plugin
- #784 - @asaha2 - Support name and id filters for list op

## [v1.137.0] - 2025-02-12

- #782 - @apinonformoso - fix partner interconnect json tag
- #781 - @dylanrhysscott - CON-11810 Implement GetNodePoolTemplate endpoint for DOKS godo client

## [v1.136.0] - 2025-01-28

- #776 - @danaelhe - Databases: Support online-migrations
Expand Down
2 changes: 1 addition & 1 deletion godo.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
)

const (
libraryVersion = "1.136.0"
libraryVersion = "1.138.0"
defaultBaseURL = "https://api.digitalocean.com/"
userAgent = "godo/" + libraryVersion
mediaType = "application/json"
Expand Down
8 changes: 8 additions & 0 deletions kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ type KubernetesClusterCreateRequest struct {
SurgeUpgrade bool `json:"surge_upgrade"`
ControlPlaneFirewall *KubernetesControlPlaneFirewall `json:"control_plane_firewall,omitempty"`
ClusterAutoscalerConfiguration *KubernetesClusterAutoscalerConfiguration `json:"cluster_autoscaler_configuration,omitempty"`
RoutingAgent *KubernetesRoutingAgent `json:"routing_agent,omitempty"`
}

// KubernetesClusterUpdateRequest represents a request to update a Kubernetes cluster.
Expand All @@ -95,6 +96,7 @@ type KubernetesClusterUpdateRequest struct {
SurgeUpgrade bool `json:"surge_upgrade,omitempty"`
ControlPlaneFirewall *KubernetesControlPlaneFirewall `json:"control_plane_firewall,omitempty"`
ClusterAutoscalerConfiguration *KubernetesClusterAutoscalerConfiguration `json:"cluster_autoscaler_configuration,omitempty"`
RoutingAgent *KubernetesRoutingAgent `json:"routing_agent,omitempty"`

// Convert cluster to run highly available control plane
HA *bool `json:"ha,omitempty"`
Expand Down Expand Up @@ -214,6 +216,7 @@ type KubernetesCluster struct {
RegistryEnabled bool `json:"registry_enabled,omitempty"`
ControlPlaneFirewall *KubernetesControlPlaneFirewall `json:"control_plane_firewall,omitempty"`
ClusterAutoscalerConfiguration *KubernetesClusterAutoscalerConfiguration `json:"cluster_autoscaler_configuration,omitempty"`
RoutingAgent *KubernetesRoutingAgent `json:"routing_agent,omitempty"`

Status *KubernetesClusterStatus `json:"status,omitempty"`
CreatedAt time.Time `json:"created_at,omitempty"`
Expand Down Expand Up @@ -256,6 +259,11 @@ type KubernetesControlPlaneFirewall struct {
AllowedAddresses []string `json:"allowed_addresses"`
}

// KubernetesRoutingAgent represents information about the routing-agent cluster plugin.
type KubernetesRoutingAgent struct {
Enabled *bool `json:"enabled"`
}

// KubernetesClusterAutoscalerConfiguration represents Kubernetes cluster autoscaler configuration.
type KubernetesClusterAutoscalerConfiguration struct {
ScaleDownUtilizationThreshold *float64 `json:"scale_down_utilization_threshold"`
Expand Down
38 changes: 34 additions & 4 deletions kubernetes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ func TestKubernetesClusters_ListClusters(t *testing.T) {
Status: &KubernetesClusterStatus{
State: KubernetesClusterStatusRunning,
},
RoutingAgent: &KubernetesRoutingAgent{
Enabled: PtrTo(true),
},
NodePools: []*KubernetesNodePool{
{
ID: "1a17a012-cb31-4886-a787-deadbeef1191",
Expand Down Expand Up @@ -122,6 +125,9 @@ func TestKubernetesClusters_ListClusters(t *testing.T) {
"status": {
"state": "running"
},
"routing_agent": {
"enabled": true
},
"node_pools": [
{
"id": "1a17a012-cb31-4886-a787-deadbeef1191",
Expand Down Expand Up @@ -263,6 +269,9 @@ func TestKubernetesClusters_Get(t *testing.T) {
Status: &KubernetesClusterStatus{
State: KubernetesClusterStatusRunning,
},
RoutingAgent: &KubernetesRoutingAgent{
Enabled: PtrTo(true),
},
NodePools: []*KubernetesNodePool{
{
ID: "deadbeef-dead-beef-dead-deadbeefb4b3",
Expand Down Expand Up @@ -314,6 +323,9 @@ func TestKubernetesClusters_Get(t *testing.T) {
"status": {
"state": "running"
},
"routing_agent": {
"enabled": true
},
"node_pools": [
{
"id": "deadbeef-dead-beef-dead-deadbeefb4b3",
Expand Down Expand Up @@ -559,6 +571,9 @@ func TestKubernetesClusters_Create(t *testing.T) {
VPCUUID: "880b7f98-f062-404d-b33c-458d545696f6",
HA: true,
SurgeUpgrade: true,
RoutingAgent: &KubernetesRoutingAgent{
Enabled: PtrTo(true),
},
NodePools: []*KubernetesNodePool{
{
ID: "8d91899c-0739-4a1a-acc5-deadbeefbb8a",
Expand Down Expand Up @@ -594,6 +609,9 @@ func TestKubernetesClusters_Create(t *testing.T) {
ServiceSubnet: want.ServiceSubnet,
SurgeUpgrade: true,
HA: true,
RoutingAgent: &KubernetesRoutingAgent{
Enabled: PtrTo(true),
},
NodePools: []*KubernetesNodePoolCreateRequest{
{
Size: want.NodePools[0].Size,
Expand Down Expand Up @@ -626,6 +644,9 @@ func TestKubernetesClusters_Create(t *testing.T) {
"vpc_uuid": "880b7f98-f062-404d-b33c-458d545696f6",
"ha": true,
"surge_upgrade": true,
"routing_agent": {
"enabled": true
},
"node_pools": [
{
"id": "8d91899c-0739-4a1a-acc5-deadbeefbb8a",
Expand Down Expand Up @@ -824,6 +845,9 @@ func TestKubernetesClusters_Update(t *testing.T) {
ScaleDownUtilizationThreshold: &scaleDownUtilizationThreshold,
ScaleDownUnneededTime: &scaleDownUnneededTime,
},
RoutingAgent: &KubernetesRoutingAgent{
Enabled: PtrTo(true),
},
}
updateRequest := &KubernetesClusterUpdateRequest{
Name: want.Name,
Expand All @@ -840,6 +864,9 @@ func TestKubernetesClusters_Update(t *testing.T) {
ScaleDownUtilizationThreshold: &scaleDownUtilizationThreshold,
ScaleDownUnneededTime: &scaleDownUnneededTime,
},
RoutingAgent: &KubernetesRoutingAgent{
Enabled: PtrTo(true),
},
}

jBlob := `
Expand Down Expand Up @@ -883,13 +910,16 @@ func TestKubernetesClusters_Update(t *testing.T) {
]
},
"cluster_autoscaler_configuration": {
"scale_down_utilization_threshold": 0.2,
"scale_down_unneeded_time": "1m27s"
}
"scale_down_utilization_threshold": 0.2,
"scale_down_unneeded_time": "1m27s"
},
"routing_agent": {
"enabled": true
}
}
}`

expectedReqJSON := `{"name":"antoine-test-cluster","tags":["cluster-tag-1","cluster-tag-2"],"maintenance_policy":{"start_time":"00:00","duration":"","day":"monday"},"surge_upgrade":true,"control_plane_firewall":{"enabled":true,"allowed_addresses":["1.2.3.4/32"]},"cluster_autoscaler_configuration":{"scale_down_utilization_threshold":0.2,"scale_down_unneeded_time":"1m27s"}}
expectedReqJSON := `{"name":"antoine-test-cluster","tags":["cluster-tag-1","cluster-tag-2"],"maintenance_policy":{"start_time":"00:00","duration":"","day":"monday"},"surge_upgrade":true,"control_plane_firewall":{"enabled":true,"allowed_addresses":["1.2.3.4/32"]},"cluster_autoscaler_configuration":{"scale_down_utilization_threshold":0.2,"scale_down_unneeded_time":"1m27s"},"routing_agent":{"enabled":true}}
`

mux.HandleFunc("/v2/kubernetes/clusters/8d91899c-0739-4a1a-acc5-deadbeefbb8f", func(w http.ResponseWriter, r *http.Request) {
Expand Down
68 changes: 68 additions & 0 deletions load_balancers.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ const (
type LoadBalancersService interface {
Get(context.Context, string) (*LoadBalancer, *Response, error)
List(context.Context, *ListOptions) ([]LoadBalancer, *Response, error)
ListByNames(context.Context, []string, *ListOptions) ([]LoadBalancer, *Response, error)
ListByUUIDs(context.Context, []string, *ListOptions) ([]LoadBalancer, *Response, error)
Create(context.Context, *LoadBalancerRequest) (*LoadBalancer, *Response, error)
Update(ctx context.Context, lbID string, lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error)
Delete(ctx context.Context, lbID string) (*Response, error)
Expand Down Expand Up @@ -403,6 +405,72 @@ func (l *LoadBalancersServiceOp) List(ctx context.Context, opt *ListOptions) ([]
return root.LoadBalancers, resp, err
}

// ListByNames lists load balancers filtered by resource names, with optional pagination.
func (l *LoadBalancersServiceOp) ListByNames(ctx context.Context, names []string, opt *ListOptions) ([]LoadBalancer, *Response, error) {
path, err := addOptions(loadBalancersBasePath, opt)
if err != nil {
return nil, nil, err
}

req, err := l.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

q := req.URL.Query()
for _, name := range names {
q.Add("names", name)
}
req.URL.RawQuery = q.Encode()

root := new(loadBalancersRoot)
resp, err := l.client.Do(ctx, req, root)
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
}

return root.LoadBalancers, resp, err
}

// ListByUUIDs lists load balancers filtered by resource UUIDs, with optional pagination.
func (l *LoadBalancersServiceOp) ListByUUIDs(ctx context.Context, uuids []string, opt *ListOptions) ([]LoadBalancer, *Response, error) {
path, err := addOptions(loadBalancersBasePath, opt)
if err != nil {
return nil, nil, err
}

req, err := l.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

q := req.URL.Query()
for _, uuid := range uuids {
q.Add("uuids", uuid)
}
req.URL.RawQuery = q.Encode()

root := new(loadBalancersRoot)
resp, err := l.client.Do(ctx, req, root)
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
}

return root.LoadBalancers, resp, err
}

// Create a new load balancer with a given configuration.
func (l *LoadBalancersServiceOp) Create(ctx context.Context, lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error) {
req, err := l.client.NewRequest(ctx, http.MethodPost, loadBalancersBasePath, lbr)
Expand Down
Loading

0 comments on commit 4c22bd3

Please sign in to comment.