From 6cd6ab0bab2661a8112e0d8f2057af99fb3cc528 Mon Sep 17 00:00:00 2001 From: Radhika Rao Date: Mon, 27 Apr 2026 17:24:02 +0530 Subject: [PATCH 1/7] fixed go.sum --- go.mod | 2 +- go.sum | 4 +- .../github.com/digitalocean/godo/CHANGELOG.md | 19 ++ .../github.com/digitalocean/godo/apps.gen.go | 24 +- .../digitalocean/godo/apps_accessors.go | 40 +++ .../digitalocean/godo/batch_inference.go | 271 ++++++++++++++++++ vendor/github.com/digitalocean/godo/godo.go | 5 +- .../digitalocean/godo/gradientai.go | 8 + .../digitalocean/godo/kubernetes.go | 35 ++- .../digitalocean/godo/nfs_actions.go | 2 +- vendor/modules.txt | 2 +- 11 files changed, 392 insertions(+), 20 deletions(-) create mode 100644 vendor/github.com/digitalocean/godo/batch_inference.go diff --git a/go.mod b/go.mod index ef34eaa06..7ba1e0c9b 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.25.0 require ( github.com/blang/semver v3.5.1+incompatible github.com/creack/pty v1.1.21 - github.com/digitalocean/godo v1.184.1-0.20260410132851-6a015e2e3b32 + github.com/digitalocean/godo v1.188.0 github.com/docker/cli v24.0.5+incompatible github.com/docker/docker v25.0.6+incompatible github.com/docker/docker-credential-helpers v0.7.0 // indirect diff --git a/go.sum b/go.sum index b8cbff8c1..af4e8d51b 100644 --- a/go.sum +++ b/go.sum @@ -91,8 +91,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.184.1-0.20260410132851-6a015e2e3b32 h1:bO0M6ODWgllf/LlR0wzlxIxiMMcJuHvlrQdDfhC4ufY= -github.com/digitalocean/godo v1.184.1-0.20260410132851-6a015e2e3b32/go.mod h1:xQsWpVCCbkDrWisHA72hPzPlnC+4W5w/McZY5ij9uvU= +github.com/digitalocean/godo v1.188.0 h1:QDxgjWnJYRf3JStAY9KM0xUqPC1YfXkPQWUMRRzraCk= +github.com/digitalocean/godo v1.188.0/go.mod h1:xQsWpVCCbkDrWisHA72hPzPlnC+4W5w/McZY5ij9uvU= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/cli v24.0.5+incompatible h1:WeBimjvS0eKdH4Ygx+ihVq1Q++xg36M/rMi4aXAvodc= diff --git a/vendor/github.com/digitalocean/godo/CHANGELOG.md b/vendor/github.com/digitalocean/godo/CHANGELOG.md index f0d9f0c1e..d64a55bef 100644 --- a/vendor/github.com/digitalocean/godo/CHANGELOG.md +++ b/vendor/github.com/digitalocean/godo/CHANGELOG.md @@ -1,5 +1,24 @@ # Change Log +## [1.188.0] - 2026-04-27 + +- #1000 - @m3co-code - add new fields to k8s node pool template for auto-scaler + +## [1.187.0] - 2026-04-22 + +- #998 - @nhenning-do - Add BatchInferenceService for the inference proxy batch API +- #995 - @d-honeybadger - DOKS: per cluster sso config + +## [1.186.0] - 2026-04-15 + +- #992 - @venkatranabothu - Add model benchmark_score and pricing + +## [1.185.0] - 2026-04-14 + +- #990 - @greeshmapill - APPS-12973: Add request based autoscaling changes to app spec +- #989 - @andrehernandez0 - NfsAction - type inconsistency bug fix +- #988 - @divyanshgupta-dodeveloper - NFRNC-701: Added provider model id to accommodate schema updates in DI Creation request + ## [1.184.0] - 2026-04-01 - #984 - Change ContextWindow to string diff --git a/vendor/github.com/digitalocean/godo/apps.gen.go b/vendor/github.com/digitalocean/godo/apps.gen.go index bf18d3e2a..a542043bf 100644 --- a/vendor/github.com/digitalocean/godo/apps.gen.go +++ b/vendor/github.com/digitalocean/godo/apps.gen.go @@ -124,7 +124,7 @@ const ( AppAlertSpecOperator_LessThan AppAlertSpecOperator = "LESS_THAN" ) -// AppAlertSpecRule - CPU_UTILIZATION: Represents CPU for a given container instance. Only applicable at the component level. - MEM_UTILIZATION: Represents RAM for a given container instance. Only applicable at the component level. - RESTART_COUNT: Represents restart count for a given container instance. Only applicable at the component level. - DEPLOYMENT_FAILED: Represents whether a deployment has failed. Only applicable at the app level. - DEPLOYMENT_LIVE: Represents whether a deployment has succeeded. Only applicable at the app level. - DEPLOYMENT_STARTED: Represents whether a deployment has started. Only applicable at the app level. - DEPLOYMENT_CANCELED: Represents whether a deployment has been canceled. Only applicable at the app level. - DOMAIN_FAILED: Represents whether a domain configuration has failed. Only applicable at the app level. - DOMAIN_LIVE: Represents whether a domain configuration has succeeded. Only applicable at the app level. - AUTOSCALE_FAILED: Represents whether autoscaling has failed. Only applicable at the app level. - AUTOSCALE_SUCCEEDED: Represents whether autoscaling has succeeded. Only applicable at the app level. - FUNCTIONS_ACTIVATION_COUNT: Represents an activation count for a given functions instance. Only applicable to functions components. - FUNCTIONS_AVERAGE_DURATION_MS: Represents the average duration for function runtimes. Only applicable to functions components. - FUNCTIONS_ERROR_RATE_PER_MINUTE: Represents an error rate per minute for a given functions instance. Only applicable to functions components. - FUNCTIONS_AVERAGE_WAIT_TIME_MS: Represents the average wait time for functions. Only applicable to functions components. - FUNCTIONS_ERROR_COUNT: Represents an error count for a given functions instance. Only applicable to functions components. - FUNCTIONS_GB_RATE_PER_SECOND: Represents the rate of memory consumption (GB x seconds) for functions. Only applicable to functions components. +// AppAlertSpecRule - CPU_UTILIZATION: Represents CPU for a given container instance. Only applicable at the component level. - MEM_UTILIZATION: Represents RAM for a given container instance. Only applicable at the component level. - RESTART_COUNT: Represents restart count for a given container instance. Only applicable at the component level. - DEPLOYMENT_FAILED: Represents whether a deployment has failed. Only applicable at the app level. - DEPLOYMENT_LIVE: Represents whether a deployment has succeeded. Only applicable at the app level. - DEPLOYMENT_STARTED: Represents whether a deployment has started. Only applicable at the app level. - DEPLOYMENT_CANCELED: Represents whether a deployment has been canceled. Only applicable at the app level. - DOMAIN_FAILED: Represents whether a domain configuration has failed. Only applicable at the app level. - DOMAIN_LIVE: Represents whether a domain configuration has succeeded. Only applicable at the app level. - AUTOSCALE_FAILED: Represents whether autoscaling has failed. Only applicable at the app level. - AUTOSCALE_SUCCEEDED: Represents whether autoscaling has succeeded. Only applicable at the app level. - JOB_INVOCATION_FAILED: Represents whether a job invocation has failed. Only applicable to scheduled job components. - FUNCTIONS_ACTIVATION_COUNT: Represents an activation count for a given functions instance. Only applicable to functions components. - FUNCTIONS_AVERAGE_DURATION_MS: Represents the average duration for function runtimes. Only applicable to functions components. - FUNCTIONS_ERROR_RATE_PER_MINUTE: Represents an error rate per minute for a given functions instance. Only applicable to functions components. - FUNCTIONS_AVERAGE_WAIT_TIME_MS: Represents the average wait time for functions. Only applicable to functions components. - FUNCTIONS_ERROR_COUNT: Represents an error count for a given functions instance. Only applicable to functions components. - FUNCTIONS_GB_RATE_PER_SECOND: Represents the rate of memory consumption (GB x seconds) for functions. Only applicable to functions components. - REQUESTS_PER_SECOND: Represents requests per second for a service. Only applicable to service components. - REQUEST_DURATION_P95_MS: Represents request duration p95 in milliseconds for a service. Only applicable to service components. type AppAlertSpecRule string // List of AppAlertSpecRule @@ -148,6 +148,8 @@ const ( AppAlertSpecRule_FunctionsAverageWaitTimeMs AppAlertSpecRule = "FUNCTIONS_AVERAGE_WAIT_TIME_MS" AppAlertSpecRule_FunctionsErrorCount AppAlertSpecRule = "FUNCTIONS_ERROR_COUNT" AppAlertSpecRule_FunctionsGBRatePerSecond AppAlertSpecRule = "FUNCTIONS_GB_RATE_PER_SECOND" + AppAlertSpecRule_RequestsPerSecond AppAlertSpecRule = "REQUESTS_PER_SECOND" + AppAlertSpecRule_RequestDurationP95Ms AppAlertSpecRule = "REQUEST_DURATION_P95_MS" ) // AppAlertSpecWindow the model 'AppAlertSpecWindow' @@ -177,9 +179,23 @@ type AppAutoscalingSpecMetricCPU struct { Percent int64 `json:"percent,omitempty"` } +// AppAutoscalingSpecMetricRequestDuration struct for AppAutoscalingSpecMetricRequestDuration +type AppAutoscalingSpecMetricRequestDuration struct { + // The p95 target request duration in milliseconds for the component. + P95Milliseconds int64 `json:"p95_milliseconds,omitempty"` +} + +// AppAutoscalingSpecMetricRequestsPerSecond struct for AppAutoscalingSpecMetricRequestsPerSecond +type AppAutoscalingSpecMetricRequestsPerSecond struct { + // The target number of requests per second per instance for the component. + PerInstance int64 `json:"per_instance,omitempty"` +} + // AppAutoscalingSpecMetrics struct for AppAutoscalingSpecMetrics type AppAutoscalingSpecMetrics struct { - CPU *AppAutoscalingSpecMetricCPU `json:"cpu,omitempty"` + CPU *AppAutoscalingSpecMetricCPU `json:"cpu,omitempty"` + RequestsPerSecond *AppAutoscalingSpecMetricRequestsPerSecond `json:"requests_per_second,omitempty"` + RequestDuration *AppAutoscalingSpecMetricRequestDuration `json:"request_duration,omitempty"` } // AppBuildConfig struct for AppBuildConfig @@ -756,13 +772,15 @@ type AppWorkerSpecTermination struct { type AutoscalerActionScaleChange struct { From int64 `json:"from,omitempty"` To int64 `json:"to,omitempty"` + // The metric that triggered the scale change while scaling up. Known values are \"cpu\", \"requests_per_second\", \"request_duration\". For inactivity sleep, \"scale_from_zero\" and \"scale_to_zero\" are used. + TriggeringMetric string `json:"triggering_metric,omitempty"` } // AutoscalingEventComponentScaleChange struct for AutoscalingEventComponentScaleChange type AutoscalingEventComponentScaleChange struct { From int64 `json:"from,omitempty"` To int64 `json:"to,omitempty"` - // The metric that triggered the scale change while scaling up. Known values are "cpu", "requests_per_second", "request_duration". For inactivity sleep, "scale_from_zero" and "scale_to_zero" are used. + // The metric that triggered the scale change while scaling up. Known values are \"cpu\", \"requests_per_second\", \"request_duration\". For inactivity sleep, \"scale_from_zero\" and \"scale_to_zero\" are used. TriggeringMetric string `json:"triggering_metric,omitempty"` } diff --git a/vendor/github.com/digitalocean/godo/apps_accessors.go b/vendor/github.com/digitalocean/godo/apps_accessors.go index d105e8a9c..5dcdeb1b3 100644 --- a/vendor/github.com/digitalocean/godo/apps_accessors.go +++ b/vendor/github.com/digitalocean/godo/apps_accessors.go @@ -405,6 +405,22 @@ func (a *AppAutoscalingSpecMetricCPU) GetPercent() int64 { return a.Percent } +// GetP95Milliseconds returns the P95Milliseconds field. +func (a *AppAutoscalingSpecMetricRequestDuration) GetP95Milliseconds() int64 { + if a == nil { + return 0 + } + return a.P95Milliseconds +} + +// GetPerInstance returns the PerInstance field. +func (a *AppAutoscalingSpecMetricRequestsPerSecond) GetPerInstance() int64 { + if a == nil { + return 0 + } + return a.PerInstance +} + // GetCPU returns the CPU field. func (a *AppAutoscalingSpecMetrics) GetCPU() *AppAutoscalingSpecMetricCPU { if a == nil { @@ -413,6 +429,22 @@ func (a *AppAutoscalingSpecMetrics) GetCPU() *AppAutoscalingSpecMetricCPU { return a.CPU } +// GetRequestDuration returns the RequestDuration field. +func (a *AppAutoscalingSpecMetrics) GetRequestDuration() *AppAutoscalingSpecMetricRequestDuration { + if a == nil { + return nil + } + return a.RequestDuration +} + +// GetRequestsPerSecond returns the RequestsPerSecond field. +func (a *AppAutoscalingSpecMetrics) GetRequestsPerSecond() *AppAutoscalingSpecMetricRequestsPerSecond { + if a == nil { + return nil + } + return a.RequestsPerSecond +} + // GetCNBVersioning returns the CNBVersioning field. func (a *AppBuildConfig) GetCNBVersioning() *AppBuildConfigCNBVersioning { if a == nil { @@ -2637,6 +2669,14 @@ func (a *AutoscalerActionScaleChange) GetTo() int64 { return a.To } +// GetTriggeringMetric returns the TriggeringMetric field. +func (a *AutoscalerActionScaleChange) GetTriggeringMetric() string { + if a == nil { + return "" + } + return a.TriggeringMetric +} + // GetFrom returns the From field. func (a *AutoscalingEventComponentScaleChange) GetFrom() int64 { if a == nil { diff --git a/vendor/github.com/digitalocean/godo/batch_inference.go b/vendor/github.com/digitalocean/godo/batch_inference.go new file mode 100644 index 000000000..b75242f65 --- /dev/null +++ b/vendor/github.com/digitalocean/godo/batch_inference.go @@ -0,0 +1,271 @@ +package godo + +import ( + "context" + "fmt" + "io" + "net/http" + "net/url" +) + +const ( + defaultBatchInferenceBaseURL = "https://inference.do-ai.run/" + batchInferenceBasePath = "v1/batches" + batchInferenceFilePath = batchInferenceBasePath + "/files" + batchInferenceByIDPath = batchInferenceBasePath + "/%s" + batchInferenceResultsPath = batchInferenceBasePath + "/%s/results" + batchInferenceCancelPath = batchInferenceBasePath + "/%s/cancel" +) + +// BatchInferenceService is an interface for managing batch inference jobs +// via the inference proxy at inference.do-ai.run. +type BatchInferenceService interface { + CreatePresignedUploadURL(context.Context, *CreateBatchFileRequest) (*CreateBatchFileResponse, *Response, error) + UploadInputFile(ctx context.Context, uploadURL string, content io.Reader) (*Response, error) + CreateJob(context.Context, *CreateBatchRequest) (*Batch, *Response, error) + ListJobs(context.Context, *ListBatchesOptions) (*ListBatchesResponse, *Response, error) + GetJob(context.Context, string) (*Batch, *Response, error) + CancelJob(context.Context, string) (*Batch, *Response, error) + GetJobResult(context.Context, string) (*BatchResultsResponse, *Response, error) +} + +// BatchInferenceServiceOp handles communication with the batch inference +// endpoints on the inference proxy (inference.do-ai.run). +type BatchInferenceServiceOp struct { + client *Client + baseURL *url.URL +} + +var _ BatchInferenceService = &BatchInferenceServiceOp{} + +// -- Request types -- + +// CreateBatchFileRequest represents a request to create a presigned URL for +// uploading a batch JSONL input file. +type CreateBatchFileRequest struct { + FileName string `json:"file_name"` +} + +// CreateBatchRequest represents a request to create a batch inference job. +// Provider is always required. Endpoint is required only when Provider is "openai". +type CreateBatchRequest struct { + Provider string `json:"provider"` + FileID string `json:"file_id"` + CompletionWindow string `json:"completion_window"` + RequestID string `json:"request_id,omitempty"` + Endpoint string `json:"endpoint,omitempty"` +} + +// ListBatchesOptions specifies optional query parameters for listing batch jobs. +type ListBatchesOptions struct { + After string `url:"after,omitempty"` + Limit int `url:"limit,omitempty"` + Status string `url:"status,omitempty"` +} + +// -- Response types -- + +// CreateBatchFileResponse is returned when creating a presigned file upload URL. +type CreateBatchFileResponse struct { + FileID string `json:"file_id"` + UploadURL string `json:"upload_url"` + ExpiresAt string `json:"expires_at"` +} + +// BatchRequestCounts holds per-request completion counts for a batch job. +type BatchRequestCounts struct { + Total int `json:"total"` + Completed int `json:"completed"` + Failed int `json:"failed"` +} + +// Batch represents a batch inference job returned by the inference proxy. +// Timestamps are ISO 8601 strings. Nullable fields use *string. +type Batch struct { + BatchID string `json:"batch_id"` + Provider string `json:"provider"` + FileID string `json:"file_id"` + CompletionWindow string `json:"completion_window"` + Status string `json:"status"` + RequestID string `json:"request_id"` + RequestCounts *BatchRequestCounts `json:"request_counts,omitempty"` + ResultAvailable bool `json:"result_available"` + CancelRequestedAt *string `json:"cancel_requested_at"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + ExpiresAt *string `json:"expires_at"` +} + +// BatchEdge is a single edge in the Relay-style batch list response. +type BatchEdge struct { + Cursor string `json:"cursor"` + Node Batch `json:"node"` +} + +// BatchPageInfo holds forward-only pagination info for batch listing. +type BatchPageInfo struct { + EndCursor string `json:"endCursor"` + HasNextPage bool `json:"hasNextPage"` +} + +// ListBatchesResponse is returned by GET /v1/batches. +// Uses Relay-style cursor pagination. +type ListBatchesResponse struct { + Edges []BatchEdge `json:"edges"` + PageInfo BatchPageInfo `json:"page_info"` +} + +// BatchResultsDownload holds the presigned download URL and its expiry. +type BatchResultsDownload struct { + PresignedURL string `json:"presigned_url"` + ExpiresAt string `json:"expires_at"` +} + +// BatchResultsResponse is returned by GET /v1/batches/{batch_id}/results. +type BatchResultsResponse struct { + Download BatchResultsDownload `json:"download"` + OutputFileID string `json:"output_file_id"` +} + +// -- helpers -- + +// newRequest builds an HTTP request resolved against the inference proxy base URL +// rather than the default api.digitalocean.com. The resulting absolute URL is +// passed to Client.NewRequest so that standard headers and auth are applied. +func (s *BatchInferenceServiceOp) newRequest(ctx context.Context, method, path string, body interface{}) (*http.Request, error) { + rel, err := url.Parse(path) + if err != nil { + return nil, err + } + u := s.baseURL.ResolveReference(rel) + return s.client.NewRequest(ctx, method, u.String(), body) +} + +// -- Service methods -- + +// CreatePresignedUploadURL creates a presigned URL for uploading a batch JSONL input file. +func (s *BatchInferenceServiceOp) CreatePresignedUploadURL(ctx context.Context, createReq *CreateBatchFileRequest) (*CreateBatchFileResponse, *Response, error) { + req, err := s.newRequest(ctx, http.MethodPost, batchInferenceFilePath, createReq) + if err != nil { + return nil, nil, err + } + + root := new(CreateBatchFileResponse) + resp, err := s.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + return root, resp, nil +} + +// UploadInputFile uploads batch JSONL content to a presigned S3 URL returned by +// CreatePresignedUploadURL. A plain HTTP client is used (no Authorization header) +// because the presigned URL already embeds authentication in its query parameters. +func (s *BatchInferenceServiceOp) UploadInputFile(ctx context.Context, uploadURL string, content io.Reader) (*Response, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodPut, uploadURL, content) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/x-ndjson") + + resp, err := (&http.Client{}).Do(req) + if err != nil { + return nil, err + } + defer func() { + io.Copy(io.Discard, resp.Body) + resp.Body.Close() + }() + + response := newResponse(resp) + if err := CheckResponse(resp); err != nil { + return response, err + } + return response, nil +} + +// CreateJob creates a new batch inference job. +func (s *BatchInferenceServiceOp) CreateJob(ctx context.Context, createReq *CreateBatchRequest) (*Batch, *Response, error) { + req, err := s.newRequest(ctx, http.MethodPost, batchInferenceBasePath, createReq) + if err != nil { + return nil, nil, err + } + + root := new(Batch) + resp, err := s.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + return root, resp, nil +} + +// ListJobs returns a list of batch inference jobs with optional filtering and pagination. +func (s *BatchInferenceServiceOp) ListJobs(ctx context.Context, opts *ListBatchesOptions) (*ListBatchesResponse, *Response, error) { + path, err := addOptions(batchInferenceBasePath, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.newRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + + root := new(ListBatchesResponse) + resp, err := s.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + return root, resp, nil +} + +// GetJob retrieves a batch inference job by ID. +func (s *BatchInferenceServiceOp) GetJob(ctx context.Context, batchID string) (*Batch, *Response, error) { + path := fmt.Sprintf(batchInferenceByIDPath, batchID) + + req, err := s.newRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + + root := new(Batch) + resp, err := s.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + return root, resp, nil +} + +// CancelJob requests cancellation of a batch inference job. +func (s *BatchInferenceServiceOp) CancelJob(ctx context.Context, batchID string) (*Batch, *Response, error) { + path := fmt.Sprintf(batchInferenceCancelPath, batchID) + + req, err := s.newRequest(ctx, http.MethodPost, path, nil) + if err != nil { + return nil, nil, err + } + + root := new(Batch) + resp, err := s.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + return root, resp, nil +} + +// GetJobResult retrieves the result download URLs for a completed batch inference job. +func (s *BatchInferenceServiceOp) GetJobResult(ctx context.Context, batchID string) (*BatchResultsResponse, *Response, error) { + path := fmt.Sprintf(batchInferenceResultsPath, batchID) + + req, err := s.newRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + + root := new(BatchResultsResponse) + resp, err := s.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + return root, resp, nil +} diff --git a/vendor/github.com/digitalocean/godo/godo.go b/vendor/github.com/digitalocean/godo/godo.go index cab0dbe84..038048695 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.184.0" + libraryVersion = "1.188.0" defaultBaseURL = "https://api.digitalocean.com/" userAgent = "godo/" + libraryVersion mediaType = "application/json" @@ -101,6 +101,7 @@ type Client struct { PartnerAttachment PartnerAttachmentService GradientAI GradientAIService DedicatedInference DedicatedInferenceService + BatchInference BatchInferenceService BYOIPPrefixes BYOIPPrefixesService // Optional function called after every successful request made to the DO APIs onRequestCompleted RequestCompletionCallback @@ -333,6 +334,8 @@ func NewClient(httpClient *http.Client) *Client { c.PartnerAttachment = &PartnerAttachmentServiceOp{client: c} c.GradientAI = &GradientAIServiceOp{client: c} c.DedicatedInference = &DedicatedInferenceServiceOp{client: c} + batchInferenceURL, _ := url.Parse(defaultBatchInferenceBaseURL) + c.BatchInference = &BatchInferenceServiceOp{client: c, baseURL: batchInferenceURL} c.headers = make(map[string]string) diff --git a/vendor/github.com/digitalocean/godo/gradientai.go b/vendor/github.com/digitalocean/godo/gradientai.go index 57285ba59..9bb8a96f7 100644 --- a/vendor/github.com/digitalocean/godo/gradientai.go +++ b/vendor/github.com/digitalocean/godo/gradientai.go @@ -541,6 +541,7 @@ type ChatBot struct { // Model represents a Gradient AI Model type Model struct { Agreement *Agreement `json:"agreement,omitempty"` + BenchmarkScore json.RawMessage `json:"benchmark_score,omitempty"` Capabilities []string `json:"capabilities,omitempty"` ContextWindow string `json:"context_window,omitempty"` CreatedAt *Timestamp `json:"created_at,omitempty"` @@ -553,6 +554,7 @@ type Model struct { Name string `json:"name,omitempty"` ParameterCount float64 `json:"parameter_count,omitempty"` ParentUuid string `json:"parent_uuid,omitempty"` + Pricing *ModelPricing `json:"pricing,omitempty"` Provider string `json:"provider,omitempty"` Type string `json:"type,omitempty"` UpdatedAt *Timestamp `json:"updated_at,omitempty"` @@ -583,6 +585,12 @@ type ModelVersion struct { Patch int `json:"patch,omitempty"` } +// ModelPricing represents the pricing per million tokens for a model +type ModelPricing struct { + InputPricePerMillion float64 `json:"input_price_per_million,omitempty"` + OutputPricePerMillion float64 `json:"output_price_per_million,omitempty"` +} + // AgentCreateRequest represents the request to create a new Gradient AI Agent type AgentCreateRequest struct { AnthropicKeyUuid string `json:"anthropic_key_uuid,omitempty"` diff --git a/vendor/github.com/digitalocean/godo/kubernetes.go b/vendor/github.com/digitalocean/godo/kubernetes.go index 2b6c5f3c6..303f22334 100644 --- a/vendor/github.com/digitalocean/godo/kubernetes.go +++ b/vendor/github.com/digitalocean/godo/kubernetes.go @@ -27,7 +27,7 @@ type KubernetesService interface { Get(context.Context, string) (*KubernetesCluster, *Response, error) GetUser(context.Context, string) (*KubernetesClusterUser, *Response, error) GetUpgrades(context.Context, string) ([]*KubernetesVersion, *Response, error) - GetKubeConfig(context.Context, string) (*KubernetesClusterConfig, *Response, error) + GetKubeConfig(context.Context, string, *KubernetesClusterKubeconfigGetRequest) (*KubernetesClusterConfig, *Response, error) GetKubeConfigWithExpiry(context.Context, string, int64) (*KubernetesClusterConfig, *Response, error) GetCredentials(context.Context, string, *KubernetesClusterCredentialsGetRequest) (*KubernetesClusterCredentials, *Response, error) List(context.Context, *ListOptions) ([]*KubernetesCluster, *Response, error) @@ -188,6 +188,11 @@ type KubernetesClusterCredentialsGetRequest struct { ExpirySeconds *int `json:"expiry_seconds,omitempty"` } +// KubernetesClusterKubeconfigGetRequest is a request to get cluster kubeconfig. +type KubernetesClusterKubeconfigGetRequest struct { + Type string `json:"type,omitempty"` +} + // KubernetesClusterRegistryRequest represents clusters to integrate with docr registry type KubernetesClusterRegistryRequest struct { ClusterUUIDs []string `json:"cluster_uuids,omitempty"` @@ -325,11 +330,11 @@ type KubernetesRdmaSharedDevicePlugin struct { } // KubernetesClusterSSO configures Single Sign-On (SSO) for a Kubernetes cluster. -// Identity Provider (IDP) settings for SSO are set up on the team level, -// whereas on a per-cluster level, users can enable or require SSO for the cluster. type KubernetesClusterSSO struct { - Enabled *bool `json:"enabled,omitempty"` - Required *bool `json:"required,omitempty"` + Enabled bool `json:"enabled"` + Required bool `json:"required"` + IssuerURL string `json:"issuer_url,omitempty"` + ClientID string `json:"client_id,omitempty"` } // KubernetesMaintenancePolicyDay represents the possible days of a maintenance @@ -506,15 +511,17 @@ type KubernetesNodePoolTemplate struct { // This follows https://pkg.go.dev/k8s.io/kubernetes@v1.32.1/pkg/scheduler/framework#Resource to represent // node resources within the node object. type KubernetesNodePoolResources struct { - CPU int64 `json:"cpu,omitempty"` - Memory string `json:"memory,omitempty"` - Pods int64 `json:"pods,omitempty"` + CPU int64 `json:"cpu,omitempty"` // deprecated in favor of cpuMilliCores + CpuMilliCores int64 `json:"cpu_milli_cores,omitempty"` + Memory string `json:"memory,omitempty"` + Pods int64 `json:"pods,omitempty"` } // KubernetesNodePoolGPUResources exposes model and GPU count of a node pool template type KubernetesNodePoolGPUResources struct { - Model string `json:"model"` - Count int64 `json:"count"` + Vendor string `json:"vendor"` + Model string `json:"model"` + Count int64 `json:"count"` } // KubernetesNode represents a Node in a node pool in a Kubernetes cluster. @@ -793,12 +800,17 @@ type KubernetesClusterConfig struct { } // GetKubeConfig returns a Kubernetes config file for the specified cluster. -func (svc *KubernetesServiceOp) GetKubeConfig(ctx context.Context, clusterID string) (*KubernetesClusterConfig, *Response, error) { +func (svc *KubernetesServiceOp) GetKubeConfig(ctx context.Context, clusterID string, get *KubernetesClusterKubeconfigGetRequest) (*KubernetesClusterConfig, *Response, error) { path := fmt.Sprintf("%s/%s/kubeconfig", kubernetesClustersPath, clusterID) req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil) if err != nil { return nil, nil, err } + q := req.URL.Query() + if get.Type != "" { + q.Add("type", get.Type) + } + req.URL.RawQuery = q.Encode() configBytes := bytes.NewBuffer(nil) resp, err := svc.client.Do(ctx, req, configBytes) if err != nil { @@ -811,6 +823,7 @@ func (svc *KubernetesServiceOp) GetKubeConfig(ctx context.Context, clusterID str } // GetKubeConfigWithExpiry returns a Kubernetes config file for the specified cluster with expiry_seconds. +// Expiry only makes sense for token-based kubeconfigs. func (svc *KubernetesServiceOp) GetKubeConfigWithExpiry(ctx context.Context, clusterID string, expirySeconds int64) (*KubernetesClusterConfig, *Response, error) { path := fmt.Sprintf("%s/%s/kubeconfig", kubernetesClustersPath, clusterID) req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil) diff --git a/vendor/github.com/digitalocean/godo/nfs_actions.go b/vendor/github.com/digitalocean/godo/nfs_actions.go index e6a29c4d5..0f8127f36 100644 --- a/vendor/github.com/digitalocean/godo/nfs_actions.go +++ b/vendor/github.com/digitalocean/godo/nfs_actions.go @@ -28,7 +28,7 @@ var _ NfsActionsService = &NfsActionsServiceOp{} // NfsAction represents an NFS action type NfsAction struct { - ID int `json:"id"` + ID string `json:"id"` Status string `json:"status"` Type string `json:"type"` StartedAt *Timestamp `json:"started_at"` diff --git a/vendor/modules.txt b/vendor/modules.txt index 86c6d3a5e..3d1bbbe19 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -61,7 +61,7 @@ github.com/creack/pty # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc ## explicit github.com/davecgh/go-spew/spew -# github.com/digitalocean/godo v1.184.1-0.20260410132851-6a015e2e3b32 +# github.com/digitalocean/godo v1.188.0 ## explicit; go 1.23.0 github.com/digitalocean/godo github.com/digitalocean/godo/metrics From 2a6e347537b738644ef3f481d47641f3dad7c1f2 Mon Sep 17 00:00:00 2001 From: Radhika Rao Date: Mon, 27 Apr 2026 17:31:04 +0530 Subject: [PATCH 2/7] fixed failing unit test --- do/kubernetes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/do/kubernetes.go b/do/kubernetes.go index c57bd32ff..294f746c8 100644 --- a/do/kubernetes.go +++ b/do/kubernetes.go @@ -124,7 +124,7 @@ func (k8s *kubernetesClusterService) Get(clusterID string) (*KubernetesCluster, } func (k8s *kubernetesClusterService) GetKubeConfig(clusterID string) ([]byte, error) { - config, _, err := k8s.client.GetKubeConfig(context.TODO(), clusterID) + config, _, err := k8s.client.GetKubeConfig(context.TODO(), clusterID, nil) if err != nil { return nil, err } From f6b755973adffe896002054e0314726f5606ea85 Mon Sep 17 00:00:00 2001 From: Radhika Rao Date: Mon, 27 Apr 2026 17:45:02 +0530 Subject: [PATCH 3/7] added changes for kubernetes and nfs failing tests --- commands/kubernetes.go | 12 ++++--- commands/kubernetes_test.go | 6 ++-- commands/nfs.go | 72 ------------------------------------- commands/nfs_test.go | 20 +---------- 4 files changed, 12 insertions(+), 98 deletions(-) diff --git a/commands/kubernetes.go b/commands/kubernetes.go index e0a3959aa..477377360 100644 --- a/commands/kubernetes.go +++ b/commands/kubernetes.go @@ -2880,10 +2880,14 @@ func ssoConfigFromArgs(c *CmdConfig) (*godo.KubernetesClusterSSO, error) { return nil, fmt.Errorf("getting %s flag value: %w", doctl.ArgKubernetesRequireSSO, err) } if enableSSO != nil || requireSSO != nil { - return &godo.KubernetesClusterSSO{ - Enabled: enableSSO, - Required: requireSSO, - }, nil + sso := &godo.KubernetesClusterSSO{} + if enableSSO != nil { + sso.Enabled = *enableSSO + } + if requireSSO != nil { + sso.Required = *requireSSO + } + return sso, nil } return nil, nil } diff --git a/commands/kubernetes_test.go b/commands/kubernetes_test.go index 1e1b588a6..5fdb8abb5 100644 --- a/commands/kubernetes_test.go +++ b/commands/kubernetes_test.go @@ -554,8 +554,8 @@ func TestKubernetesCreate(t *testing.T) { Enabled: boolPtr(true), }, SSO: &godo.KubernetesClusterSSO{ - Enabled: boolPtr(true), - Required: boolPtr(false), + Enabled: true, + Required: false, }, } tm.kubernetes.EXPECT().Create(&r).Return(&testCluster, nil) @@ -664,7 +664,7 @@ func TestKubernetesUpdate(t *testing.T) { Enabled: boolPtr(true), }, SSO: &godo.KubernetesClusterSSO{ - Enabled: boolPtr(true), + Enabled: true, }, } tm.kubernetes.EXPECT().Update(testCluster.ID, &r).Return(&testCluster, nil) diff --git a/commands/nfs.go b/commands/nfs.go index d7b19e7aa..83f65aa55 100644 --- a/commands/nfs.go +++ b/commands/nfs.go @@ -251,18 +251,6 @@ func nfsSnapshotCreate(c *CmdConfig) error { return err } - wait, err := c.Doit.GetBool(c.NS, doctl.ArgCommandWait) - if err != nil { - return err - } - - if wait { - _, err := actionWait(c, action.ID, 5) - if err != nil { - return err - } - } - item := &displayers.NfsAction{NfsActions: []do.NfsAction{*action}} return c.Display(item) } @@ -335,18 +323,6 @@ func nfsResize(c *CmdConfig) error { return err } - wait, err := c.Doit.GetBool(c.NS, doctl.ArgCommandWait) - if err != nil { - return err - } - - if wait { - _, err := actionWait(c, action.ID, 5) - if err != nil { - return err - } - } - item := &displayers.NfsAction{NfsActions: []do.NfsAction{*action}} return c.Display(item) } @@ -369,18 +345,6 @@ func nfsAttach(c *CmdConfig) error { return err } - wait, err := c.Doit.GetBool(c.NS, doctl.ArgCommandWait) - if err != nil { - return err - } - - if wait { - _, err := actionWait(c, action.ID, 5) - if err != nil { - return err - } - } - item := &displayers.NfsAction{NfsActions: []do.NfsAction{*action}} return c.Display(item) } @@ -402,18 +366,6 @@ func nfsDetach(c *CmdConfig) error { return err } - wait, err := c.Doit.GetBool(c.NS, doctl.ArgCommandWait) - if err != nil { - return err - } - - if wait { - _, err := actionWait(c, action.ID, 5) - if err != nil { - return err - } - } - item := &displayers.NfsAction{NfsActions: []do.NfsAction{*action}} return c.Display(item) } @@ -437,18 +389,6 @@ func nfsReassign(c *CmdConfig) error { return err } - wait, err := c.Doit.GetBool(c.NS, doctl.ArgCommandWait) - if err != nil { - return err - } - - if wait { - _, err := actionWait(c, action.ID, 5) - if err != nil { - return err - } - } - item := &displayers.NfsAction{NfsActions: []do.NfsAction{*action}} return c.Display(item) } @@ -469,18 +409,6 @@ func nfsSwitchPerformanceTier(c *CmdConfig) error { return err } - wait, err := c.Doit.GetBool(c.NS, doctl.ArgCommandWait) - if err != nil { - return err - } - - if wait { - _, err := actionWait(c, action.ID, 5) - if err != nil { - return err - } - } - item := &displayers.NfsAction{NfsActions: []do.NfsAction{*action}} return c.Display(item) } diff --git a/commands/nfs_test.go b/commands/nfs_test.go index 21d7eb887..5eef861a0 100644 --- a/commands/nfs_test.go +++ b/commands/nfs_test.go @@ -49,7 +49,7 @@ var ( } testNfsAction = do.NfsAction{ NfsAction: &godo.NfsAction{ - ID: 123456, + ID: "123456", Status: "in-progress", Type: "snapshot", }, @@ -304,9 +304,6 @@ func TestRunNfsSnapshotCreate(t *testing.T) { withTestClient(t, func(config *CmdConfig, tm *tcMocks) { if !tc.expectErr { tm.nfsActions.EXPECT().Snapshot(tc.shareID, tc.snapName, tc.region).Return(&testNfsAction, nil) - if tc.wait { - tm.actions.EXPECT().Get(testNfsAction.ID).Return(&testAction, nil) - } } config.Doit.Set(config.NS, "name", tc.snapName) @@ -366,9 +363,6 @@ func TestRunNfsResize(t *testing.T) { if !tc.expectErr && tc.size != "invalid" { size := uint64(2048) tm.nfsActions.EXPECT().Resize(tc.id, size, tc.region).Return(&testNfsAction, nil) - if tc.wait { - tm.actions.EXPECT().Get(testNfsAction.ID).Return(&testAction, nil) - } } config.Doit.Set(config.NS, "id", tc.id) @@ -420,9 +414,6 @@ func TestRunNfsAttach(t *testing.T) { if !tc.expectErr { vpcID := "vpc-1234" tm.nfsActions.EXPECT().Attach(tc.id, vpcID, tc.region).Return(&testNfsAction, nil) - if tc.wait { - tm.actions.EXPECT().Get(testNfsAction.ID).Return(&testAction, nil) - } } config.Doit.Set(config.NS, "id", tc.id) @@ -474,9 +465,6 @@ func TestRunNfsDetach(t *testing.T) { if !tc.expectErr { vpcID := "vpc-1234" tm.nfsActions.EXPECT().Detach(tc.id, vpcID, tc.region).Return(&testNfsAction, nil) - if tc.wait { - tm.actions.EXPECT().Get(testNfsAction.ID).Return(&testAction, nil) - } } config.Doit.Set(config.NS, "id", tc.id) @@ -527,9 +515,6 @@ func TestRunNfsReassign(t *testing.T) { withTestClient(t, func(config *CmdConfig, tm *tcMocks) { if !tc.expectErr { tm.nfsActions.EXPECT().Reassign(tc.id, tc.oldVpcID, tc.newVpcID).Return(&testNfsAction, nil) - if tc.wait { - tm.actions.EXPECT().Get(testNfsAction.ID).Return(&testAction, nil) - } } config.Doit.Set(config.NS, "id", tc.id) @@ -577,9 +562,6 @@ func TestRunNfsSwitchPerformanceTier(t *testing.T) { withTestClient(t, func(config *CmdConfig, tm *tcMocks) { if !tc.expectErr { tm.nfsActions.EXPECT().SwitchPerformanceTier(tc.id, tc.performanceTier).Return(&testNfsAction, nil) - if tc.wait { - tm.actions.EXPECT().Get(testNfsAction.ID).Return(&testAction, nil) - } } config.Doit.Set(config.NS, "id", tc.id) From d292655d207d30ba56157354169fb331db7fe821 Mon Sep 17 00:00:00 2001 From: Radhika Rao Date: Mon, 27 Apr 2026 17:54:09 +0530 Subject: [PATCH 4/7] fixed integration test for kubernetes.go --- do/kubernetes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/do/kubernetes.go b/do/kubernetes.go index 294f746c8..c93fa4a8e 100644 --- a/do/kubernetes.go +++ b/do/kubernetes.go @@ -124,7 +124,7 @@ func (k8s *kubernetesClusterService) Get(clusterID string) (*KubernetesCluster, } func (k8s *kubernetesClusterService) GetKubeConfig(clusterID string) ([]byte, error) { - config, _, err := k8s.client.GetKubeConfig(context.TODO(), clusterID, nil) + config, _, err := k8s.client.GetKubeConfig(context.TODO(), clusterID, &godo.KubernetesClusterKubeconfigGetRequest{}) if err != nil { return nil, err } From f8dfc13ee3f1543e4001a3e9c33cc4f6e8ffc282 Mon Sep 17 00:00:00 2001 From: Radhika Rao Date: Mon, 27 Apr 2026 19:20:12 +0530 Subject: [PATCH 5/7] added back wait --- commands/nfs.go | 80 ++++++++++++++++++++++++++++++++++++++++++++ commands/nfs_test.go | 18 ++++++++++ 2 files changed, 98 insertions(+) diff --git a/commands/nfs.go b/commands/nfs.go index 83f65aa55..e3553405c 100644 --- a/commands/nfs.go +++ b/commands/nfs.go @@ -251,6 +251,18 @@ func nfsSnapshotCreate(c *CmdConfig) error { return err } + wait, err := c.Doit.GetBool(c.NS, doctl.ArgCommandWait) + if err != nil { + return err + } + + if wait { + _, err := nfsActionWait(c, action.ID, 5) + if err != nil { + return err + } + } + item := &displayers.NfsAction{NfsActions: []do.NfsAction{*action}} return c.Display(item) } @@ -323,6 +335,18 @@ func nfsResize(c *CmdConfig) error { return err } + wait, err := c.Doit.GetBool(c.NS, doctl.ArgCommandWait) + if err != nil { + return err + } + + if wait { + _, err := nfsActionWait(c, action.ID, 5) + if err != nil { + return err + } + } + item := &displayers.NfsAction{NfsActions: []do.NfsAction{*action}} return c.Display(item) } @@ -345,6 +369,18 @@ func nfsAttach(c *CmdConfig) error { return err } + wait, err := c.Doit.GetBool(c.NS, doctl.ArgCommandWait) + if err != nil { + return err + } + + if wait { + _, err := nfsActionWait(c, action.ID, 5) + if err != nil { + return err + } + } + item := &displayers.NfsAction{NfsActions: []do.NfsAction{*action}} return c.Display(item) } @@ -366,6 +402,18 @@ func nfsDetach(c *CmdConfig) error { return err } + wait, err := c.Doit.GetBool(c.NS, doctl.ArgCommandWait) + if err != nil { + return err + } + + if wait { + _, err := nfsActionWait(c, action.ID, 5) + if err != nil { + return err + } + } + item := &displayers.NfsAction{NfsActions: []do.NfsAction{*action}} return c.Display(item) } @@ -389,6 +437,18 @@ func nfsReassign(c *CmdConfig) error { return err } + wait, err := c.Doit.GetBool(c.NS, doctl.ArgCommandWait) + if err != nil { + return err + } + + if wait { + _, err := nfsActionWait(c, action.ID, 5) + if err != nil { + return err + } + } + item := &displayers.NfsAction{NfsActions: []do.NfsAction{*action}} return c.Display(item) } @@ -409,10 +469,30 @@ func nfsSwitchPerformanceTier(c *CmdConfig) error { return err } + wait, err := c.Doit.GetBool(c.NS, doctl.ArgCommandWait) + if err != nil { + return err + } + + if wait { + _, err := nfsActionWait(c, action.ID, 5) + if err != nil { + return err + } + } + item := &displayers.NfsAction{NfsActions: []do.NfsAction{*action}} return c.Display(item) } +func nfsActionWait(c *CmdConfig, actionID string, pollTime int) (*do.Action, error) { + id, err := strconv.Atoi(actionID) + if err != nil { + return nil, fmt.Errorf("invalid action ID %q: %w", actionID, err) + } + return actionWait(c, id, pollTime) +} + func displayNfs(c *CmdConfig, shares ...do.Nfs) error { item := &displayers.Nfs{NfsShares: shares} return c.Display(item) diff --git a/commands/nfs_test.go b/commands/nfs_test.go index 5eef861a0..dab69dee2 100644 --- a/commands/nfs_test.go +++ b/commands/nfs_test.go @@ -304,6 +304,9 @@ func TestRunNfsSnapshotCreate(t *testing.T) { withTestClient(t, func(config *CmdConfig, tm *tcMocks) { if !tc.expectErr { tm.nfsActions.EXPECT().Snapshot(tc.shareID, tc.snapName, tc.region).Return(&testNfsAction, nil) + if tc.wait { + tm.actions.EXPECT().Get(123456).Return(&testAction, nil) + } } config.Doit.Set(config.NS, "name", tc.snapName) @@ -363,6 +366,9 @@ func TestRunNfsResize(t *testing.T) { if !tc.expectErr && tc.size != "invalid" { size := uint64(2048) tm.nfsActions.EXPECT().Resize(tc.id, size, tc.region).Return(&testNfsAction, nil) + if tc.wait { + tm.actions.EXPECT().Get(123456).Return(&testAction, nil) + } } config.Doit.Set(config.NS, "id", tc.id) @@ -414,6 +420,9 @@ func TestRunNfsAttach(t *testing.T) { if !tc.expectErr { vpcID := "vpc-1234" tm.nfsActions.EXPECT().Attach(tc.id, vpcID, tc.region).Return(&testNfsAction, nil) + if tc.wait { + tm.actions.EXPECT().Get(123456).Return(&testAction, nil) + } } config.Doit.Set(config.NS, "id", tc.id) @@ -465,6 +474,9 @@ func TestRunNfsDetach(t *testing.T) { if !tc.expectErr { vpcID := "vpc-1234" tm.nfsActions.EXPECT().Detach(tc.id, vpcID, tc.region).Return(&testNfsAction, nil) + if tc.wait { + tm.actions.EXPECT().Get(123456).Return(&testAction, nil) + } } config.Doit.Set(config.NS, "id", tc.id) @@ -515,6 +527,9 @@ func TestRunNfsReassign(t *testing.T) { withTestClient(t, func(config *CmdConfig, tm *tcMocks) { if !tc.expectErr { tm.nfsActions.EXPECT().Reassign(tc.id, tc.oldVpcID, tc.newVpcID).Return(&testNfsAction, nil) + if tc.wait { + tm.actions.EXPECT().Get(123456).Return(&testAction, nil) + } } config.Doit.Set(config.NS, "id", tc.id) @@ -562,6 +577,9 @@ func TestRunNfsSwitchPerformanceTier(t *testing.T) { withTestClient(t, func(config *CmdConfig, tm *tcMocks) { if !tc.expectErr { tm.nfsActions.EXPECT().SwitchPerformanceTier(tc.id, tc.performanceTier).Return(&testNfsAction, nil) + if tc.wait { + tm.actions.EXPECT().Get(123456).Return(&testAction, nil) + } } config.Doit.Set(config.NS, "id", tc.id) From 8846d58c2701eab93cbb51d1e0545f3b848b8b33 Mon Sep 17 00:00:00 2001 From: Radhika Rao Date: Mon, 27 Apr 2026 21:37:21 +0530 Subject: [PATCH 6/7] changed k8 cluster sso --- commands/kubernetes.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/commands/kubernetes.go b/commands/kubernetes.go index 477377360..ff8d1b940 100644 --- a/commands/kubernetes.go +++ b/commands/kubernetes.go @@ -2879,17 +2879,15 @@ func ssoConfigFromArgs(c *CmdConfig) (*godo.KubernetesClusterSSO, error) { if err != nil { return nil, fmt.Errorf("getting %s flag value: %w", doctl.ArgKubernetesRequireSSO, err) } - if enableSSO != nil || requireSSO != nil { - sso := &godo.KubernetesClusterSSO{} - if enableSSO != nil { - sso.Enabled = *enableSSO - } - if requireSSO != nil { - sso.Required = *requireSSO - } - return sso, nil + + sso := &godo.KubernetesClusterSSO{} + if enableSSO != nil { + sso.Enabled = *enableSSO + } + if requireSSO != nil { + sso.Required = *requireSSO } - return nil, nil + return sso, nil } func boolPtr(val bool) *bool { From 3d5d9104eae9a5ddd3160dfc62fd519c0f1df039 Mon Sep 17 00:00:00 2001 From: Radhika Rao Date: Mon, 27 Apr 2026 21:42:01 +0530 Subject: [PATCH 7/7] added changes --- commands/kubernetes.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/commands/kubernetes.go b/commands/kubernetes.go index ff8d1b940..c10acd519 100644 --- a/commands/kubernetes.go +++ b/commands/kubernetes.go @@ -2880,6 +2880,9 @@ func ssoConfigFromArgs(c *CmdConfig) (*godo.KubernetesClusterSSO, error) { return nil, fmt.Errorf("getting %s flag value: %w", doctl.ArgKubernetesRequireSSO, err) } + if enableSSO == nil && requireSSO == nil { + return nil, nil + } sso := &godo.KubernetesClusterSSO{} if enableSSO != nil { sso.Enabled = *enableSSO